home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / mxcode / soundss2 / sbmod.asm < prev    next >
Assembly Source File  |  1994-08-24  |  86KB  |  3,402 lines

  1. ;
  2. ;       ╔═══════════════════════════════════════════════╗
  3. ;       ║                                               ║
  4. TITLE   ║ SOUNDBLASTER MODPLAYER  (SB/SBPRO/16 & COMP.) ║
  5. ;       ║                                               ║
  6. ;       ╚═══════════════════════════════════════════════╝
  7. ;
  8. ; THIS MODULE PLAYER WAS CODED IN EARLY 1994
  9. ;
  10. ;                        BY SILVIO TURELLO (FRONTMAN/CREW242)
  11. ;
  12. ; IT IS A COMPLETELY REVISED VERSION OF THE MODLIB
  13. ;
  14. ;                        BY SERGE HUBER (NUMERUS/IMPHOBIA)
  15. ;
  16. ; PC-CONVERSION OF AMIGA PROTRACKER CODE (FOR SUPER PRO PLAY > MODLIB)
  17. ;
  18. ;                        BY JOSHUA C. JENSEN (CYBERSTRIKE/FORM. RENAISSANCE)
  19. ;
  20. ; ORIGIN SOURCE CODE CAME FROM THE PROTRACKER V2.1A
  21. ;
  22. ;                        BY LARS "ZAP" HAMRE (AMIGA FREELANCERS)
  23. ;
  24. ; FEATURES: 4/8-CHANNEL-MODS (M.K./FLT4/FLT8/8CHN), MIXINGRATE 10000-22222 HZ
  25. ;
  26. ;           1/2-FX-CHANNELS, FULL MOD-FX SUPPORT EXCEPT FILTER & REVERSE FUNK
  27. ;
  28. ;           STEREO FOR SBPRO&16, ONLY 10% (APPROX.) PERFORMANCE REDUCTION
  29. ;
  30. ;           544 KB EMS-MEMORY SUPPORT FOR FX
  31. ;
  32. DOSSEG
  33. .MODEL TINY
  34. STACKLENGTH     = 0100H
  35. ASSUME CS:DGROUP, DS:DGROUP; SS:DGROUP
  36. ;=============================================================================
  37. MAX_CHAN_NUMB    = 8
  38. IRQ1            = 20H
  39. IRQ2        = 21H
  40. IRQ3        =0A0H
  41. IRQ4        =0A1H
  42. TIMER0        = 40H
  43. PIT1            = 43H
  44. UHR_INDEX    = 70H
  45. UHR_PORT    = 71H
  46. UHR_STATA    = 0AH
  47. UHR_STATB    = 0BH
  48. UHR_STATC    = 0CH
  49. ;-----------------------------------------------------------------------------
  50. .DATA
  51. PROG_START_SEG  DW 0
  52. PROG_END_SEG    DW 0
  53. SYSTEM        DB 0
  54. IRQCOUNT    DB 56
  55. SBPRO_FLAG    DB 0        ;0=SB, 1= SBPRO
  56. SB_TYP        DB 1        ;0=GUS, 1=SBPRO, 2=SB, 3=NO_SOUND
  57. SB_MODUS    DB 0        ;0=MUSIC&FX 1=MUSIC 2=FX 3=NO_SOUND
  58. SAM_FLAG    DB 0        ;FLIP SAMPLE CHANNEL
  59. SAMPLE_RATE    DW 22222
  60. SBP_MIXERI    DW 0224H
  61. SBP_MIXERD    DW 0225H
  62. SB_RESET    DW 0226H
  63. SB_READ        DW 022AH
  64. SB_WRITE    DW 022CH
  65. SB_RSTAT    DW 022EH
  66. IRQ_NUMBER    DB 7
  67. DMA_CHANNEL    DB 1
  68. DMA_RATE    DB 211
  69. DMA_PAGE    DB 0
  70. DMA_POFF    DW 0
  71. DMA_DATA    DB 87H,83H,81H,82H
  72. MAINFREQ    DD 41236
  73. DMA_CX        DW 434
  74. DMA_MORE    DW 434*4
  75. DMA_MAX        DW 434*16
  76. DMA_NEWPTR    DW 0
  77. DMA_PTR        DW 0
  78. DMA_SEG        DW 0
  79. DMA_OFFSET    DW 0
  80. MIXMUL_OFFSET    DW 0
  81. COMP_SPEED2     DW 0106H
  82. COMP_SPEED3     DW 4006H
  83. COMP_SPEED4     DW 0
  84. COMP_SPEED5     DW 1165
  85. HOLD70  LABEL   DWORD
  86.         DW OFFSET TIMER_HANDLER, 0
  87. HOLDSB  LABEL   DWORD
  88.         DW OFFSET SBIRQ_HANDLER, 0
  89. STEREO_PANNING    DW 2,-2,0,2,0,-2,0,2,0
  90. ;-----------------------------------------------------------------------------
  91. GDDLENGTH    DD 0
  92. GDDREST        DW 0
  93. GDDHANDLE    DW 0
  94. ;GDDMIN        DW -1
  95. ;GDDNEW        DW 0
  96. ;GDDPOSL    DW 0
  97. ;GDDPOSH    DW 0
  98. GDDZEIG        DB 0
  99. ;-----------------------------------------------------------------------------
  100. ERROR1_TEXT    DB "MOD ERROR",13,10,"$"
  101. ERROR2_TEXT    DB "FX ERROR",13,10,"$"
  102. ERROR3_TEXT    DB "SB ERROR",13,10,"$"
  103. OUT_TEXT    DB "+/- VOLUME",13,10
  104.         DB "1   PLAY SAMPLE",13,10
  105.         DB "9   INIT REPEAT",13,10
  106.         DB "0   MUSIC MODE",13,10,"$"
  107. SAMPLE_NAME    DB "SAMPLE1.SAM",0
  108. CONFIG_NAME     DB "SS.CFG",0
  109. VOL_NAME        DB "FM.VOL",0
  110. CFG_TEXT1       DB "DEFAULT MUSIC SYSTEM = ",0
  111. CFG_TEXT2       DB "DEFAULT MUSIC MODE = ",0
  112. CFG_TEXT3       DB "SOUNDCARD BASE PORT = ",0
  113. CFG_TEXT4       DB "SOUNDCARD IRQ NUMBER = ",0
  114. CFG_TEXT5       DB "SOUNDCARD DMA NUMBER = ",0
  115. CFG_TEXT6       DB "DEFAULT SAMPLINGRATE = ",0
  116. CFG_TEXT7       DB "SYSTEM COMPATIBILITY = ",0
  117. ;-----------------------------------------------------------------------------
  118. ; PLAYER - CONTROL STRUCTURES
  119. ;-----------------------------------------------------------------------------
  120. ALIGN 2
  121. MUSIC_VOL    DB 255
  122. MUSIC_VOLUME    DB 255
  123. FX_VOL        DB 255
  124. FX_VOLUME    DB 255
  125. MASTER_VOLUME    DB 255
  126. MOD_STAT    DB 0
  127. BPM_COUNT    DB 1
  128. BPM_SPEED    DB 20
  129. CH_NUMB        DW 4
  130. QUEUE_BUFFER    LABEL    WORD        ;256 BYTES
  131. NOTE        DW MAX_CHAN_NUMB DUP(0)
  132. CMD        DB MAX_CHAN_NUMB DUP(0)
  133. CMDLO        DB MAX_CHAN_NUMB DUP(0)
  134. START        DW MAX_CHAN_NUMB DUP(0)
  135. LENGTHI        DW MAX_CHAN_NUMB DUP(0)
  136. LOOPSTART    DW MAX_CHAN_NUMB DUP(0)
  137. REPLEN        DW MAX_CHAN_NUMB DUP(0)
  138. PERIOD        DW MAX_CHAN_NUMB DUP(0)
  139. FINETUNE    DB MAX_CHAN_NUMB DUP(0)
  140. VOLUME        DB MAX_CHAN_NUMB DUP(0)
  141. TONEPORTDIREC    DB MAX_CHAN_NUMB DUP(1)
  142. TONEPORTSPEED    DB MAX_CHAN_NUMB DUP(0)
  143. WANTEDPERIOD    DW MAX_CHAN_NUMB DUP(0)
  144. VIBRATOCMD    DB MAX_CHAN_NUMB DUP(0)
  145. VIBRATOPOS    DB MAX_CHAN_NUMB DUP(0)
  146. TREMOLOCMD    DB MAX_CHAN_NUMB DUP(0)
  147. TREMOLOPOS    DB MAX_CHAN_NUMB DUP(0)
  148. WAVECONTROL    DB MAX_CHAN_NUMB DUP(0)
  149. GLISSFUNK    DB MAX_CHAN_NUMB DUP(0)
  150. SAMPLEOFFSET    DB MAX_CHAN_NUMB DUP(0)
  151. PATTPOS        DB MAX_CHAN_NUMB DUP(0)
  152. LOOPCOUNT    DB MAX_CHAN_NUMB DUP(0)
  153.  
  154. MFREQ        DW MAX_CHAN_NUMB DUP(0)
  155. MOFLOW        DB MAX_CHAN_NUMB DUP(0)
  156. SONG_DATA    LABEL    BYTE        ;128 BYTES
  157. MVOL        DB MAX_CHAN_NUMB DUP(0)
  158. MSEG        DW MAX_CHAN_NUMB DUP(0)
  159. MOFS        DW MAX_CHAN_NUMB DUP(0)
  160. MREPEAT        DW MAX_CHAN_NUMB DUP(0)
  161. MREPLEN        DW MAX_CHAN_NUMB DUP(0)
  162. MMAXREP        DW MAX_CHAN_NUMB DUP(0)
  163. MOD_NAME    DB 40 DUP(0)
  164. ;-----------------------------------------------------------------------------
  165. ; Seg                           Stores the segment of the current sample.  If
  166. ;                               the segment is zero, then there is no sample
  167. ;                               begin played.
  168. ; Offset                        The current offset of the sample being played
  169. ;                               in the segment specified.
  170. ; MaxRep                        The offset of the place in the sample to
  171. ;                               repeat from (i.e. the end of the sample).
  172. ; Freq                          The frequency to be played out the output
  173. ;                               device.  It is actually a playback period,
  174. ;                               the upper byte determining the number of
  175. ;                               bytes to be added to the sample offset each
  176. ;                               interrupt, and the lower byte to be added
  177. ;                               over and over to generate carry flags to be
  178. ;                               added to additional offsets.
  179. ; Vol                           The actual volume to multiply the frequency
  180. ;                               by.
  181. ; Repeat                        The place to repeat from when the end of the
  182. ;                               loop is found.
  183. ; RepLen                        The number of bytes from Repeat to go to.
  184. ;                               When the end of this is found, it goes back
  185. ;                               to Repeat.
  186. ; OFlow                         The overflow variable used to generate the
  187. ;                               carry flags.
  188. ;-----------------------------------------------------------------------------
  189. ; PROTRACKER VARIABLES
  190. ;-----------------------------------------------------------------------------
  191. ALIGN 2
  192. MT_SPEED                DB 6
  193. MT_COUNTER              DB 0
  194. MT_PATTERNPOS           DW 0
  195. MT_SONGPOS              DB 0
  196. MT_PATTDELAYTIME2       DB 0
  197. MT_PATTDELAYTIME        DB 0
  198. MT_PBREAKFLAG           DB 0
  199. MT_PBREAKPOS            DB 0
  200. MT_POSJUMPFLAG          DB 0
  201. MT_LOWMASK              DB 0FFH
  202.  
  203. ALIGN 2
  204. Effect_Jump_Table1    LABEL    WORD
  205. DW OFFSET Go_Arpeggio, OFFSET Go_PortaUp, OFFSET Go_PortaDown
  206. DW OFFSET Go_TonePortamento, OFFSET Go_vibrato, OFFSET Go_TonePlusVolSlide
  207. DW OFFSET Go_VibratoPlusVolSlide, OFFSET Go_Tremolo, OFFSET Go_Return
  208. DW OFFSET Go_Return, OFFSET Go_VolumeSlide, OFFSET Go_Return, OFFSET Go_Return
  209. DW OFFSET Go_Return, OFFSET Go_E_Commands, OFFSET Go_Return
  210.  
  211. Effect_Jump_Table2    LABEL    WORD
  212. DW OFFSET Go_PerNop, OFFSET Go_PerNop, OFFSET Go_PerNop
  213. DW OFFSET Go_PerNop, OFFSET Go_PerNop, OFFSET Go_PerNop
  214. DW OFFSET Go_PerNop, OFFSET Go_PerNop, OFFSET Go_PerNop
  215. DW OFFSET Go_SampleOffset, OFFSET Go_PerNop, OFFSET Go_PositionJump
  216. DW OFFSET Go_VolumeChange, OFFSET Go_PatternBreak
  217. DW OFFSET Go_E_Commands, OFFSET Go_SetSpeed
  218.  
  219. Effect_Jump_Table3    LABEL    WORD
  220. DW OFFSET Go_Return, OFFSET Go_FinePortaUp, OFFSET Go_FinePortaDown
  221. DW OFFSET Go_SetGlissControl, OFFSET Go_SetVibratoControl
  222. DW OFFSET Go_SeTFineTune, OFFSET Go_JumpLoop, OFFSET Go_SetTremoloControl
  223. DW OFFSET Go_Return, OFFSET Go_RetrigNote, OFFSET Go_VolumeFineUp
  224. DW OFFSET Go_VolumeFineDown, OFFSET Go_NoteCut, OFFSET Go_NoteDelay
  225. DW OFFSET Go_PatternDelay, OFFSET Go_Return
  226.  
  227. ALIGN 2
  228. MT_VIBRATOTABLE        DB   0, 24, 49, 74, 97,120,141,161
  229.                         DB 180,197,212,224,235,244,250,253
  230.                         DB 255,253,250,244,235,224,212,197
  231.                         DB 180,161,141,120, 97, 74, 49, 24
  232.  
  233. ALIGN 2
  234. MT_PERIODTABLE    LABEL    WORD
  235. DW 856,808,762,720,678,640,604,570,538,508,480,453 ;C-1 to H-1 Finetune +0.
  236. DW 428,404,381,360,339,320,302,285,269,254,240,226 ;C-2 to H-2 Finetune +0.
  237. DW 214,202,190,180,170,160,151,143,135,127,120,113 ;C-3 to H-3 Finetune +0.
  238. DW 107,101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56 ;C-4 to H-4 Finetune +0.
  239.  
  240. DW 850,802,757,715,674,637,601,567,535,505,477,450 ;C-1 to H-1 Finetune +1.
  241. DW 425,401,379,357,337,318,300,284,268,253,239,225 ;C-2 to H-2 Finetune +1.
  242. DW 213,201,189,179,169,159,150,142,134,126,119,113 ;C-3 to H-3 Finetune +1.
  243. DW 106,100, 94, 89, 84, 79, 75, 71, 67, 83, 59, 56 ;C-4 to H-4 Finetune +1.
  244.  
  245. DW 844,796,752,709,670,632,597,563,532,502,474,447 ;C-1 to H-1 Finetune +2.
  246. DW 422,398,376,355,335,316,298,282,266,251,237,224 ;C-2 to H-2 Finetune +2.
  247. DW 211,199,188,177,167,158,149,141,133,125,118,112 ;C-3 to H-3 Finetune +2.
  248. DW 105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59, 56 ;C-4 to H-4 Finetune +2.
  249.  
  250. DW 838,791,746,704,665,628,592,559,528,498,470,444 ;C-1 to H-1 Finetune +3.
  251. DW 419,395,373,352,332,314,296,280,264,249,235,222 ;C-2 to H-2 Finetune +3.
  252. DW 209,198,187,176,166,157,148,140,132,125,118,111 ;C-3 to H-3 Finetune +3.
  253. DW 104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59, 55 ;C-4 to H-4 Finetune +3.
  254.  
  255. DW 832,785,741,699,660,623,588,555,524,495,467,441 ;C-1 to H-1 Finetune +4.
  256. DW 416,392,370,350,330,312,294,278,262,247,233,220 ;C-2 to H-2 Finetune +4.
  257. DW 208,196,185,175,165,156,147,139,131,124,117,110 ;C-3 to H-3 Finetune +4.
  258. DW 104, 98, 92, 87, 82, 78, 73, 69, 65, 62, 58, 55 ;C-4 to H-4 Finetune +4.
  259.  
  260. DW 826,779,736,694,655,619,584,551,520,491,463,437 ;C-1 to H-1 Finetune +5.
  261. DW 413,390,368,347,328,309,292,276,260,245,232,219 ;C-2 to H-2 Finetune +5.
  262. DW 206,195,184,174,164,155,146,138,130,123,116,109 ;C-3 to H-3 Finetune +5.
  263. DW 103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58, 54 ;C-4 to H-4 Finetune +5.
  264.  
  265. DW 820,774,730,689,651,614,580,547,516,487,460,434 ;C-1 to H-1 Finetune +6.
  266. DW 410,387,365,345,325,307,290,274,258,244,230,217 ;C-2 to H-2 Finetune +6.
  267. DW 205,193,183,172,163,154,145,137,129,122,115,109 ;C-3 to H-3 Finetune +6.
  268. DW 102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57, 54 ;C-4 to H-4 Finetune +6.
  269.  
  270. DW 814,768,725,684,646,610,575,543,513,484,457,431 ;C-1 to H-1 Finetune +7.
  271. DW 407,384,363,342,323,305,288,272,256,242,228,216 ;C-2 to H-2 Finetune +7.
  272. DW 204,192,181,171,161,152,144,136,128,121,114,108 ;C-3 to H-3 Finetune +7.
  273. DW 102, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57, 54 ;C-4 to H-4 Finetune +7.
  274.  
  275. DW 907,856,808,762,720,678,640,604,570,538,504,480 ;C-1 to H-1 Finetune -8.
  276. DW 453,428,404,381,360,339,320,302,285,269,254,240 ;C-2 to H-2 Finetune -8.
  277. DW 226,214,202,190,180,170,160,151,143,135,127,120 ;C-3 to H-3 Finetune -8.
  278. DW 113,107,101, 95, 90, 85, 80, 75, 71, 67, 63, 60 ;C-4 to H-4 Finetune -8.
  279.  
  280. DW 900,850,802,757,715,675,636,601,567,535,505,477 ;C-1 to H-1 Finetune -7.
  281. DW 450,425,401,379,357,337,318,300,284,268,253,238 ;C-2 to H-2 Finetune -7.
  282. DW 225,212,200,189,179,169,159,150,142,134,126,119 ;C-3 to H-3 Finetune -7.
  283. DW 112,106,100, 94, 89, 84, 79, 75, 71, 67, 63, 59 ;C-4 to H-4 Finetune -7.
  284.  
  285. DW 894,844,796,752,709,670,632,597,563,532,502,474 ;C-1 to H-1 Finetune -6.
  286. DW 447,422,398,376,355,335,316,298,282,266,251,237 ;C-2 to H-2 Finetune -6.
  287. DW 223,211,199,188,177,167,158,149,141,133,125,118 ;C-3 to H-3 Finetune -6.
  288. DW 111,105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59 ;C-4 to H-4 Finetune -6.
  289.  
  290. DW 887,838,791,746,704,665,628,592,559,528,498,470 ;C-1 to H-1 Finetune -5.
  291. DW 444,419,395,373,352,332,314,296,280,264,249,235 ;C-2 to H-2 Finetune -5.
  292. DW 222,209,198,187,176,166,157,148,140,132,125,118 ;C-3 to H-3 Finetune -5.
  293. DW 111,104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59 ;C-4 to H-4 Finetune -5.
  294.  
  295. DW 881,832,785,741,699,660,623,588,555,524,494,467 ;C-1 to H-1 Finetune -4.
  296. DW 441,416,392,370,350,330,312,294,278,262,247,233 ;C-2 to H-2 Finetune -4.
  297. DW 220,208,196,185,175,165,156,147,139,131,123,117 ;C-3 to H-3 Finetune -4.
  298. DW 110,104, 98, 92, 87, 82, 78, 73, 69, 65, 61, 58 ;C-4 to H-4 Finetune -4.
  299.  
  300. DW 875,826,779,736,694,655,619,584,551,520,491,463 ;C-1 to H-1 Finetune -3.
  301. DW 437,413,390,368,347,338,309,292,276,260,245,232 ;C-2 to H-2 Finetune -3.
  302. DW 219,206,195,184,174,164,155,146,138,130,123,116 ;C-3 to H-3 Finetune -3.
  303. DW 109,103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58 ;C-4 to H-4 Finetune -3.
  304.  
  305. DW 868,820,774,730,689,651,614,580,547,516,487,460 ;C-1 to H-1 Finetune -2.
  306. DW 434,410,387,365,345,325,307,290,274,258,244,230 ;C-2 to H-2 Finetune -2.
  307. DW 217,205,193,183,172,163,154,145,137,129,122,115 ;C-3 to H-3 Finetune -2.
  308. DW 108,102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57 ;C-4 to H-4 Finetune -2.
  309.  
  310. DW 862,814,768,725,684,646,610,575,543,513,484,457 ;C-1 to H-1 Finetune -1.
  311. DW 431,407,384,363,342,323,305,288,272,256,242,228 ;C-2 to H-2 Finetune -1.
  312. DW 216,203,192,181,171,161,152,144,136,128,121,114 ;C-3 to H-3 Finetune -1.
  313. DW 108,101, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57 ;C-4 to H-4 Finetune -1.
  314. ;-----------------------------------------------------------------------------
  315. ; MTM - TRACK STRUCTURE
  316. ;-----------------------------------------------------------------------------
  317. ALIGN 2
  318. TRACK_NUMBER    DW 0
  319. TRACK_INFO    DB 8 DUP(0)
  320. TRACK_SEG    DW 0
  321. TRACKS_OFFSET    DW OFFSET TRACK1_DATA, OFFSET TRACK2_DATA, OFFSET TRACK3_DATA
  322.         DW OFFSET TRACK4_DATA, OFFSET TRACK5_DATA, OFFSET TRACK6_DATA
  323.         DW OFFSET TRACK7_DATA, OFFSET TRACK8_DATA
  324. TRACK1_DATA    DB 128 DUP(0)
  325. TRACK2_DATA    DB 128 DUP(0)
  326. TRACK3_DATA    DB 128 DUP(0)
  327. TRACK4_DATA    DB 128 DUP(0)
  328. TRACK5_DATA    DB 128 DUP(0)
  329. TRACK6_DATA    DB 128 DUP(0)
  330. TRACK7_DATA    DB 128 DUP(0)
  331. TRACK8_DATA    DB 128 DUP(0)
  332. ;-----------------------------------------------------------------------------
  333. ; MOD - FILE STRUCTURE
  334. ;-----------------------------------------------------------------------------
  335. ALIGN 2
  336. SAMPLE_SIZE    DW 0
  337. PATTERN_SIZE    DW 0
  338. PATTERN_SEG    DW 0
  339. PATTERN_NUMBER    DW 0
  340. PATTERN_CURRENT    DW 0
  341. ISIZE        DW 31 DUP(0)
  342. IVOL_FINETUNE    DW 31 DUP(0)
  343. ILOOP_START    DW 31 DUP(0)
  344. ILOOP_SIZE    DW 31 DUP(0)
  345. SONG_SIZE    DB 0
  346. SONG_LOOP    DB 0
  347. MOD_SIGN    DD 0
  348. SAMPLE_SEG    DW 31 DUP(0)
  349. ;-----------------------------------------------------------------------------
  350. ; SINGLE SAMPLE VARIABLES
  351. ;-----------------------------------------------------------------------------
  352. SAMPLE_ZEIG    DW 0
  353. SAMPLE_MEM    DW 48 DUP(0)
  354. SAMPLE_BIG    DW 48 DUP(0)
  355. EMS_SEG        DW 0
  356. EMS_OFFSET    DW 0
  357. EMS_HANDLE    DW 0
  358. SAM_SEG1    DW 0
  359. SAM_SEG2    DW 0
  360. SAM_OFS1    DD 0
  361. SAM_OFS2    DD 0
  362. SAM_FRQ1    DW 0
  363. SAM_FRQ2    DW 0
  364. SAM_OFL1    DB 0
  365. SAM_OFL2    DB 0
  366. SAM_MAX1    DW 0
  367. SAM_MAX2    DW 0
  368. ;-----------------------------------------------------------------------------
  369. PROG_END        LABEL   BYTE    ;THIS MUST BE THE LAST ROW IN DATA SEGMENT!
  370. ;-----------------------------------------------------------------------------
  371.  
  372.  
  373.  
  374. .386
  375. .CODE 
  376. ORG 100H
  377. ;=============================================================================
  378. MAIN PROC NEAR
  379.     JMP    MAIN_CONT        ;0100
  380.     RETF
  381.     CALL    CONFIG_INIT        ;0104
  382.     RETF
  383.     CALL    LOAD_MOD        ;0108
  384.     RETF
  385.     CALL    PLAY_MUSIC        ;010C
  386.     RETF
  387.     CALL    STOP_MUSIC        ;0110
  388.     RETF
  389.     CALL    END_MUSIC        ;0114
  390.     RETF
  391.     CALL    LOAD_SAMPLE        ;0118
  392.     RETF
  393.     CALL    PLAY_SAMPLE        ;011C
  394.     RETF
  395.     CALL    END_SAMPLE        ;0120
  396.     RETF
  397.     CALL    SET_SAMPLERATE        ;0124
  398.     RETF
  399.     CALL    GET_VOLUME        ;0128
  400.     RETF
  401.     CALL    SET_VOLUME        ;012C
  402.     RETF
  403.     CALL    SET_SONGLOOP        ;0130
  404.     RETF
  405.     CALL    GET_SONGPOSITION    ;0134
  406.     RETF
  407.     CALL    SET_SONGPOSITION    ;0138
  408.     RETF
  409.     CALL    GET_SONGMOD        ;013C
  410.     RETF
  411.     CALL    SET_SONGMOD        ;0140
  412.     RETF
  413.     CALL    DSP_OFF            ;0144
  414.     RETF
  415.     CALL    DSP_RESET        ;0148
  416.     RETF
  417.     CALL    DSP_RESET        ;014C/FREE
  418.     RETF
  419.     CALL    DSP_RESET        ;0150/FREE
  420.     RETF
  421. MAIN ENDP
  422. ;=============================================================================
  423. ;
  424. ; MOD ROUTINES
  425. ;
  426. ;=============================================================================
  427. ; Format of a note: (ORIGINALLY MOD)
  428. ;
  429. ;                   0 0          0 0          0 0           0 0
  430. ;                   | |          | |          | |           | |
  431. ;                  /   \        / /          /   \           \ \
  432. ;         MSB of Ins.     Note        LSB Ins.  Spec. Com.   Data for special
  433. ;
  434. ; Format of a note: (MODIFIED BY LOADER)
  435. ;
  436. ;                   0 0          0 0          0 0           0 0
  437. ;                   | |          | |          | |           | |
  438. ;                  / /          /   \         \ \           \ \
  439. ;            LSB NOTE   SPEC.COM.    MSB NOTE  INSTRUMENT    DATA FOR SPECIAL
  440. ;
  441. ;╒═══════════════════════════════════════════════════════════════════════════╕
  442. ;│ DESCRIPTION: This procedure shouldn't need to be called by anything else  │
  443. ;│              but the interrupt (ever).  It handles all note updating,     │
  444. ;│              special effects, pointers, etc.                              │
  445. ;│                                                                           │
  446. ;│              *** This code came directly from the Amiga Protracker        │
  447. ;│                  playback code, written by Lars "Zap" Hamre.  Give this   │
  448. ;│                  guy a pat on the back for such excellent code.           │
  449. ;│                                                                           │
  450. ;│ BUGS       : Or rather, non-implementations.  Command EF - Funk it is     │
  451. ;│              not all the way implemented.  Command E0 - Filter is not     │
  452. ;│              implemented at all.  It is Amiga-specific, directly with     │
  453. ;│              the Paula chip.                                              │
  454. ;│                                                                           │
  455. ;│ IMPROVEMENTS:    Optimized code for PC-architecure by the Frontman        │
  456. ;│                                                                           │
  457. ;╘═══════════════════════════════════════════════════════════════════════════╛
  458. CONTROL_CHANNELS PROC NEAR
  459.     CMP    MOD_STAT,3
  460.     JAE    Go_NoNewPosYet
  461.     INC    MT_COUNTER
  462.     MOV    AL,MT_COUNTER
  463.     CMP    AL,MT_SPEED        ; Does it match the current speed?
  464.     JB    SHORT Go_NoNewNote    ; No, just do fx.
  465.     MOV    MT_COUNTER,0
  466.     CMP    MT_PATTDELAYTIME2,0
  467.     JE    SHORT Go_GetNewNote
  468.         CALL    Go_CheckEfx        ; Otherwise, just do fx only.
  469.         JMP    Go_Dskip                ; Then, jump to update block values.
  470. Go_NoNewNote:
  471.     CALL    Go_CheckEfx        ; Do fx.
  472.         JMP    Go_NoNewPosYet        ; We don't update block values
  473.                     ; when we are just doing fx.
  474. Go_GetNewNote:
  475.     MOV    ES,TRACK_SEG
  476.     XOR    SI,SI
  477. Go_PlayVoice:
  478.     PUSH    SI
  479.     MOV    DI,SI
  480.     SHL    DI,1
  481.     MOVZX    BX,MT_SONGPOS        ; BLOCK BEGINNING TO ES:BX
  482.     ADD    BX,[TRACKS_OFFSET+DI]
  483.     MOVZX    BX,[BX]
  484.     XCHG    BL,BH            ; MULTIPLY WITH 256 (TRACK-SIZE)
  485.     ADD    BX,MT_PATTERNPOS
  486.     CMP    [NOTE+DI],0        ; See if there is a note.
  487.     JNE    SHORT Go_plvskip    ; No, go on.
  488.     CMP    [CMD+SI],0
  489.     JNE    SHORT Go_plvskip
  490.     CMP    [CMDLO+SI],0
  491.     JNE    SHORT Go_plvskip
  492.     CALL    Go_PerNop        ; Otherwise, figure out the frequency.
  493. Go_plvskip:
  494.     MOV    AX,ES:[BX]        ; Load this channel's information
  495.     MOV    [NOTE+DI],AX        ; from the actual track block and
  496.     AND    [NOTE+DI],0FFFH
  497.     SHR    AH,4            ; into our own internal structure
  498.     MOV    [CMD+SI],AH        ; to access it from.
  499.     MOV    AX,ES:[BX+2]
  500.     MOV    [CMDLO+SI],AH
  501.     OR    AL,AL            ; Instrument byte.  Is there an ins?
  502.     JZ    SHORT Go_SetRegs
  503.     DEC    AL
  504.     MOVZX    BX,AL            ; GET SAMPLE SEGMENT
  505.     SHL    BX,1
  506.     MOV    AX,[SAMPLE_SEG+BX]
  507.     MOV    [START+DI],AX        ; Store it in our structure.
  508.     MOV    AX,[ISIZE+BX]        ; Get the length.
  509.     MOV    [LENGTHI+DI],AX        ; Store it appropriately.
  510.     MOV    [REPLEN+DI],AX
  511.     MOV    AX,[IVOL_FINETUNE+BX]    ; Get the instrument volume and fine tune.
  512.     MOV    [VOLUME+SI],AL        ; Store it appropriately.
  513.     MOV    [FINETUNE+SI],AH
  514.     MOV    [MVOL+SI],AL
  515.     MOV    CX,[ILOOP_SIZE+BX]    ; Get Repeat length
  516.     CMP    CX,8            ; If the length is less than four,
  517.     JB    SHORT Go_NoLoop        ; then there is no loop.
  518.     MOV    AX,[ILOOP_START+BX]    ; Get the Repeat start.
  519.     MOV    [MREPEAT+DI],AX        ; Move it into the appropriate
  520.     MOV    [LOOPSTART+DI],AX    ; structures and locations.
  521.     MOV    [REPLEN+DI],CX        ; Move the length into its storage.
  522.     ADD    AX,CX            ; We're figuring out the offset of
  523.     MOV    [MREPLEN+DI],AX
  524.     MOV    [MMAXREP+DI],AX        ; where the repeat length breaks.
  525.     JMP    SHORT Go_SetRegs    ; Skip the no loop part.
  526. Go_NoLoop:
  527.     XOR    AX,AX            ; Zero out AX.
  528.     MOV    [MREPLEN+DI],AX        ; Make sure that no loop exists and
  529.     MOV    [MREPEAT+DI],AX
  530.     MOV    [LOOPSTART+DI],AX
  531. Go_SetRegs:
  532.     CMP    [NOTE+DI],0        ; Grab the note.
  533.     JE    Go_CheckMore        ; Check the fx.
  534.     MOV    AH,[CMD+SI]        ; Get the special fx command.
  535.     MOV    AL,[CMDLO+SI]
  536.     AND    AL,0F0H            ; Mask out the bits we don't want.
  537.     CMP    AX,0E50H        ; Is there a fine tune command
  538.     JE    SHORT Go_DoSetFineTune
  539.     CMP    AH,3            ; Is it a tone portamento?
  540.     JE    SHORT Go_ChkTonePorta
  541.     CMP    AH,5            ; Is it a tone and volume slide?
  542.     JE    SHORT Go_ChkTonePorta
  543.     CMP    AH,9            ; Is it a sample offset command?
  544.     JNE    SHORT Go_SetPeriod    ; If not, go do the actual note.
  545.     PUSH    AX            ; keep the command byte in mem
  546.     CALL    Go_CheckMoreEfx
  547.     POP    AX
  548.     JMP    SHORT Go_SetPeriod    ; Go do the actual note.
  549. Go_ChkTonePorta:
  550.     CALL    Go_SetTonePorta        ; Do part of the tone portamento.
  551.     JMP    Go_CheckMore        ; Go do the fx.
  552. Go_DoSetFineTune:
  553.     PUSH    AX
  554.     CALL    Go_SetFineTune        ; Update the fine tune.
  555.     POP    AX
  556. ;-----------------------------------------------------------------------------
  557. ; ──── We are now going to find the note in the period table.  If it
  558. ; ──── doesn't exist, then no fine tuning can be performed.  If it
  559. ; ──── does, and fine tuning is specified, then we can update it.
  560. ;-----------------------------------------------------------------------------
  561. Go_SetPeriod:
  562.     MOV    CL,AH
  563.     MOV    AX,[NOTE+DI]        ; Get the note.
  564.     DEC    AX
  565.     MOV    BX,OFFSET MT_PERIODTABLE; Set pointer to beginning of table.
  566.     CMP    CL,3
  567.     JE    SHORT Seek_Period
  568.     CMP    CL,5
  569.     JNE    SHORT Go_ftufound
  570. Seek_Period:
  571.     INC    AX
  572.     MOV    CX,36+12        ; 36 periods to cycle through.
  573. Go_ftuloop:
  574.     CMP    AX,[BX]            ; Check the note against the period.
  575.     JAE    SHORT Go_Wizzyfound    ; We found it!
  576.     INC    BX
  577.     INC    BX            ; Otherwise, update the pointer and
  578.     LOOP    Go_ftuloop        ; keep looping.
  579.     JMP    SHORT Go_Wizzyfound
  580. Go_ftufound:
  581.     ADD    BX,AX
  582. Go_WizzyFound:
  583.     MOV    AL,[FINETUNE+SI]    ; Get the fine tune.
  584.     MOV    CL,(36+12)*2        ; The period table's size is 72.
  585.     MUL    CL            ; Multiply it by the fine tune.
  586.     ADD    BX,AX            ; Add it onto the pointer to point to
  587.     MOV    AX,[BX]            ; the new period and get it.
  588.     MOV    [PERIOD+DI],AX        ; Store it.
  589.     MOV    AH,[CMD+SI]        ; Get the special fx command.
  590.     MOV    AL,[CMDLO+SI]
  591.     AND    AL,0F0H            ; Mask out the bits we don't want.
  592.     CMP    AX,0ED0H
  593.     JE    SHORT Go_delnoc
  594.     MOV    AL,[WAVECONTROL+SI]    ; Get the WaveControl.
  595.     TEST    AL,00000100B        ; Amiga: BTST #2,WaveControl.
  596.     JZ    SHORT Go_vibnoc        ; If it is zero, then skip.
  597.     MOV    [VIBRATOPOS+SI],0
  598. Go_vibnoc:
  599.     TEST    AL,01000000B        ; Amiga: BTST #6,WaveControl
  600.     JZ    SHORT Go_trenoc        ; If it is zero, then skip.
  601.     MOV    [TREMOLOPOS+SI],0    ; Zero the Tremolo offset.
  602. Go_trenoc:
  603.     MOV    AX,[START+DI]        ; Get the start segment.
  604.     MOV    [MSEG+DI],AX        ; Store it to be updated.
  605.     MOV    [MOFS+DI],0        ; Set the offset to zero.
  606.     MOV    [MOFLOW+SI],0
  607.     MOV    AX,[LENGTHI+DI]
  608.     MOV    [MMAXREP+DI],AX        ; Store in MaxRepeat
  609.     MOV    CX,[PERIOD+DI]
  610.     CALL    Go_PerNop2
  611.     JMP    SHORT Go_CheckMore
  612. Go_delnoc:
  613.     MOV    AX,[MMAXREP+DI]
  614.     MOV    [MOFS+DI],AX
  615. Go_CheckMore:
  616.     CALL    Go_CheckMoreEfx
  617. Go_DoNext:
  618.     POP    SI            ;SKIP TO NEXT CHANNEL
  619.     INC    SI
  620.     CMP    SI,CH_NUMB
  621.     JB    Go_PlayVoice
  622. ;-----------------------------------------------------------------------------
  623. Go_Dskip:
  624.     ADD    MT_PATTERNPOS,4        ; Increment position by one
  625.     MOV    AL,MT_PATTDELAYTIME
  626.     OR    AL,AL
  627.     JZ    SHORT Go_dskc
  628.     MOV    MT_PATTDELAYTIME2,AL
  629.     MOV    MT_PATTDELAYTIME,0
  630. Go_dskc:
  631.     CMP    MT_PATTDELAYTIME2,0
  632.     JE    SHORT Go_dska
  633.     DEC    MT_PATTDELAYTIME2
  634.     JZ    SHORT Go_dska
  635.     SUB    MT_PATTERNPOS,4
  636. Go_dska:
  637.     CMP    MT_PBREAKFLAG,0
  638.     JE    SHORT Go_nnpysk
  639.     MOV    MT_PBREAKFLAG,0
  640.     MOVZX    AX,MT_PBREAKPOS
  641.     MOV    MT_PBREAKPOS,AH
  642.     SHL    AX,2
  643.     MOV    MT_PATTERNPOS,AX
  644. Go_nnpysk:
  645.     CMP    MT_PATTERNPOS,256
  646.     JB    SHORT Go_NoNewPosYet
  647. Go_NextPosition:
  648.     MOVZX    AX,MT_PBREAKPOS
  649.     SHL    AX,2
  650.     MOV    MT_PATTERNPOS,AX
  651.     MOV    MT_PBREAKPOS,0
  652.     MOV    MT_POSJUMPFLAG,0
  653.     MOV    AL,MT_SONGPOS
  654.     INC    AL
  655.     AND    AL,7FH
  656.     CMP    AL,SONG_SIZE
  657.     JB    SHORT Go_NoSongRestart
  658.     MOV    AL,SONG_LOOP
  659.     CMP    AL,SONG_SIZE
  660.     JB    SHORT Go_NoSongRestart
  661.     MOV    MOD_STAT,3
  662.     XOR    AL,AL
  663. Go_NoSongRestart:
  664.     MOV    MT_SONGPOS,AL
  665. Go_NoNewPosYet:
  666.     CMP    MT_POSJUMPFLAG,0
  667.     JNE    Go_NextPosition
  668.     RET
  669. CONTROL_CHANNELS ENDP
  670. ;=============================================================================
  671. Go_CheckEfx PROC NEAR
  672.     XOR    SI,SI
  673. Go_DoEfx:
  674.     PUSH    SI
  675.     MOV    DI,SI
  676.     SHL    DI,1
  677.     MOV    BL,[CMD+SI]              ; Get the special command
  678.     MOV    BH,[CMDLO+SI]
  679.     OR    BX,BX
  680.     JNZ    SHORT SetBack1
  681.     CALL    Go_PerNop
  682.     JMP    SHORT SetBack2
  683. SetBack1:
  684.     XOR    BH,BH
  685.     SHL    BX,1
  686.     CALL    [Effect_Jump_Table1+BX]
  687. SetBack2:
  688.     POP    SI
  689.     INC    SI
  690.     CMP    SI,CH_NUMB
  691.     JB    Go_DoEfx
  692. Go_Return:
  693.     RET
  694. ;-----------------------------------------------------------------------------
  695. Go_PerNop PROC NEAR
  696.     MOV    CX,[PERIOD+DI]
  697. Go_PerNop2 PROC NEAR
  698.     XOR    AX,AX
  699.     JCXZ    SHORT Go_DivZero
  700.     MOV    AX,WORD PTR MAINFREQ
  701.     MOV    DX,WORD PTR MAINFREQ+2
  702.     DIV    CX
  703. Go_DivZero:
  704.     MOV    [MFREQ+DI],AX
  705.     RET
  706. Go_PerNop2 ENDP
  707. Go_PerNop ENDP
  708. Go_CheckEfx ENDP
  709. ;=============================================================================
  710. ;
  711. ; SI IS THE CHANNEL-BYTE-INDEX, DI IS THE CHANNEL-WORD-INDEX
  712. ;
  713. ;─────────────────────────────────────────────────────────────────────────────
  714. ; Effect 0 -- Arpeggio
  715. ;─────────────────────────────────────────────────────────────────────────────
  716. Go_Arpeggio PROC NEAR
  717.     MOVZX    AX,MT_COUNTER
  718.     MOV    BL,3
  719.     MOV    CX,[PERIOD+DI]
  720.     DIV    BL
  721.     OR    AH,AH
  722.     JZ    SHORT Go_Arpeggio1
  723.     MOV    AL,[CMDLO+SI]
  724.     CMP    AH,2
  725.     JE    SHORT Go_Arpeggio2
  726.     SHR    AL,4
  727. Go_Arpeggio2:
  728.     AND    AL,0FH
  729.     SHL    AL,1
  730.     MOVZX    BX,AL
  731.     MOV    AL,[FINETUNE+SI]
  732.     MOV    DX,CX
  733.     MOV    CL,(36+12)*2
  734.     MUL    CL
  735.     PUSH    DI
  736.     MOV    DI,OFFSET MT_PERIODTABLE
  737.     ADD    DI,AX
  738.     MOV    AH,36+12
  739. Go_arploop:
  740.     MOV    CX,[BX+DI]
  741.     CMP    DX,[DI]
  742.     JAE    SHORT Go_arpafterloop
  743.         INC    DI
  744.     INC    DI
  745.     DEC    AH
  746.     JNZ    Go_arploop
  747.     POP    DI
  748.     RET
  749. Go_arpafterloop:
  750.     POP    DI
  751. Go_Arpeggio1:
  752.     CALL    Go_PerNop2
  753.         RET
  754. Go_Arpeggio ENDP
  755. ;─────────────────────────────────────────────────────────────────────────────
  756. ; Effect 1 -- Portamento Up
  757. ;─────────────────────────────────────────────────────────────────────────────
  758. Go_PortaUp PROC NEAR
  759.     MOVZX    AX,[CMDLO+SI]        ; Number to slide up (was lo)
  760.     AND    AL,MT_LOWMASK
  761.     MOV    MT_LOWMASK,0FFH
  762.     SUB    [PERIOD+DI],AX
  763.     MOV    CX,[PERIOD+DI]
  764.     CMP    CX,113
  765.     JGE    SHORT Go_PortaUSkip
  766.     MOV    CX,113
  767.     MOV    [PERIOD+DI],CX
  768. Go_PortaUSkip:
  769.     CALL    Go_PerNop2
  770.     RET
  771. Go_PortaUp ENDP
  772. ;────────────────────────────────────────────────────────────────────────────
  773. ; Effect 2 -- Portamento Down
  774. ;────────────────────────────────────────────────────────────────────────────
  775. Go_PortaDown PROC NEAR
  776.     MOVZX    AX,[CMDLO+SI]        ; Number to slide down
  777.     AND    AL,MT_LOWMASK
  778.     MOV    MT_LOWMASK,0FFH
  779.     ADD    [PERIOD+DI],AX
  780.     MOV    CX,[PERIOD+DI]
  781.     CMP    CX,856
  782.     JL    SHORT Go_PortaDSkip
  783.     MOV    CX,856
  784.     MOV    [PERIOD+DI],CX
  785. Go_PortaDSkip:
  786.     CALL    Go_PerNop2
  787.     RET
  788. Go_PortaDown ENDP
  789. ;────────────────────────────────────────────────────────────────────────────
  790. ; Effect 3 -- Tone Portamento
  791. ;────────────────────────────────────────────────────────────────────────────
  792. Go_TonePortamento PROC NEAR
  793.     MOV    AL,[CMDLO+SI]
  794.     OR    AL,AL
  795.     JZ    SHORT Go_TonePortNoChange
  796.     MOV    [TONEPORTSPEED+SI],AL
  797.     MOV    [CMDLO+SI],0
  798. Go_TonePortNoChange:
  799.     CMP    [WANTEDPERIOD+DI],0
  800.     JZ    Go_Return
  801.     MOVZX    DX,[TONEPORTSPEED+SI]
  802.     MOV    CX,[PERIOD+DI]
  803.     MOV    AX,[WANTEDPERIOD+DI]
  804.     CMP    [TONEPORTDIREC+SI],0
  805.     JNE    SHORT Go_TonePortaUp
  806. Go_TonePortaDown:
  807.     ADD    CX,DX
  808.     CMP    AX,CX
  809.     JG    SHORT Go_TonePortaSetPer
  810.     JMP    SHORT Go_TonePortaEnd
  811. Go_TonePortaUp:
  812.     SUB    CX,DX
  813.     CMP    AX,CX
  814.     JL    SHORT Go_TonePortaSetPer
  815. Go_TonePortaEnd:
  816.     MOV    CX,AX
  817.     MOV    [WANTEDPERIOD+DI],0
  818. Go_TonePortaSetPer:
  819.     MOV    [PERIOD+DI],CX
  820.     MOV    AL,[GLISSFUNK+SI]
  821.     AND    AL,0FH
  822.     JZ    SHORT Go_GlissSkip
  823.     MOV    AL,[FINETUNE+SI]
  824.     MOV    BL,(36+12)*2
  825.     MUL    BL
  826.     PUSH    DI
  827.     MOV    DI,OFFSET MT_PERIODTABLE
  828.     ADD    DI,AX
  829.     XOR    BX,BX
  830. Go_GlissLoop:
  831.     CMP    CX,[BX+DI]
  832.     JAE    SHORT Go_GlissFound
  833.     INC    BX
  834.     INC    BX
  835.     CMP    BX,(36+12)*2
  836.     JB    Go_GlissLoop
  837.     MOV    BX,(35+12)*2
  838. Go_GlissFound:
  839.     MOV    CX,[BX+DI]
  840.     POP    DI
  841. Go_GlissSkip:
  842.     CALL    Go_PerNop2
  843.     RET
  844. Go_TonePortamento ENDP
  845. ;-----------------------------------------------------------------------------
  846. Go_SetTonePorta PROC NEAR
  847.     MOV    DX,[NOTE+DI]
  848.     MOV    AL,[FINETUNE+SI]
  849.     MOV    CL,48*2            ;37
  850.     MUL    CL
  851.     PUSH    DI
  852.     MOV    DI,OFFSET MT_PERIODTABLE
  853.     ADD    DI,AX
  854.     XOR    BX,BX
  855. Go_StpLoop:
  856.     CMP    DX,[BX+DI]
  857.     JAE    SHORT Go_StpFound
  858.     INC    BX
  859.     INC    BX
  860.     CMP    BX,48*2            ;37
  861.     JB    Go_StpLoop
  862.     MOV    BX,47*2            ;35
  863. Go_StpFound:
  864.     MOV    DL,[FINETUNE+SI]
  865.     AND    DL,8
  866.     JZ    SHORT Go_StpGoss
  867.     OR    BX,BX
  868.     JZ    SHORT Go_StpGoss
  869.     DEC    BX
  870.     DEC    BX
  871. Go_StpGoss:
  872.     MOV    DX,[BX+DI]
  873.     POP    DI
  874.     MOV    [WANTEDPERIOD+DI],DX
  875.     MOV    AX,[PERIOD+DI]
  876.     MOV    [TONEPORTDIREC+SI],0
  877.     CMP    DX,AX
  878.     JE    SHORT Go_ClearTonePorta
  879.     JA    Go_Return
  880.     INC    [TONEPORTDIREC+SI]
  881.     RET
  882. Go_ClearTonePorta:
  883.     MOV    [WANTEDPERIOD+DI],0
  884.     RET
  885. Go_SetTonePorta ENDP
  886. ;────────────────────────────────────────────────────────────────────────────
  887. ; Effect 4 -- Vibrato
  888. ;────────────────────────────────────────────────────────────────────────────
  889. Go_Vibrato PROC NEAR
  890.     MOV    AL,[CMDLO+SI]
  891.     OR    AL,AL
  892.     JZ    SHORT Go_Vibrato2
  893.     MOV    BL,[VIBRATOCMD+SI]
  894.     AND    AL,0FH
  895.     JZ    SHORT Go_vibskip
  896.     AND    BL,0F0H
  897.     OR    BL,AL
  898. Go_vibskip:
  899.     MOV    AL,[CMDLO+SI]
  900.     AND    AL,0F0H
  901.     JZ    SHORT Go_vibskip2
  902.     AND    BL,0FH
  903.     OR    BL,AL
  904. Go_vibskip2:
  905.     MOV    [VIBRATOCMD+SI],BL
  906. Go_Vibrato2:
  907.     MOV    AL,[VIBRATOPOS+SI]
  908.     SHR    AL,2
  909.     AND    AX,1FH
  910.     MOV    BL,[WAVECONTROL+SI]
  911.     AND    BL,3
  912.     JZ    SHORT Go_vib_sine
  913.     SHL    AL,3
  914.     CMP    BL,1
  915.     JE    SHORT Go_vib_rampdown
  916.     MOV    BL,255
  917.     JMP    SHORT Go_vib_set
  918. Go_vib_rampdown:
  919.     CMP    [VIBRATOPOS+SI],0
  920.     JG    SHORT Go_vib_rampdown2
  921.     MOV    BL,AL
  922.     NOT    BL
  923.     JMP    SHORT Go_vib_set
  924. Go_vib_rampdown2:
  925.     MOV    BL,AL
  926.     JMP    SHORT Go_vib_set
  927. Go_vib_sine:
  928.     MOVZX    BX,AL
  929.     MOV    BL,[MT_VIBRATOTABLE+BX]
  930. Go_vib_set:
  931.     MOV    AL,[VIBRATOCMD+SI]
  932.     AND    AL,0FH
  933.     MUL    BL
  934.     SHR    AX,7
  935.     MOV    BX,AX
  936.     MOV    AX,[PERIOD+DI]
  937.     CMP    [VIBRATOPOS+SI],0
  938.     JG    SHORT Go_VibratoNeg    ; BMI
  939.     NEG    BX
  940. Go_VibratoNeg:
  941.     ADD    AX,BX
  942. Go_Vibrato3:
  943.     MOV    CX,AX
  944.     CALL    Go_PerNop2
  945.     MOV    AL,[VIBRATOCMD+SI]
  946.     AND    AL,0F0H
  947.     SHR    AL,2
  948.     ADD    [VIBRATOPOS+SI],AL
  949.     RET
  950. Go_Vibrato ENDP
  951. ;────────────────────────────────────────────────────────────────────────────
  952. ; Effect 5 -- Tone and Volume Slide
  953. ;────────────────────────────────────────────────────────────────────────────
  954. Go_TonePlusVolSlide PROC NEAR
  955.     CALL    Go_TonePortNoChange
  956.     JMP    Go_VolumeSlide
  957. Go_TonePlusVolSlide ENDP
  958. ;────────────────────────────────────────────────────────────────────────────
  959. ; Effect 6 -- Vibrato and Volume Slide
  960. ;────────────────────────────────────────────────────────────────────────────
  961. Go_VibratoPlusVolSlide PROC NEAR
  962.     CALL    Go_Vibrato2        ;was mt_vibrato2
  963.     JMP    Go_VolumeSlide
  964. Go_VibratoPlusVolSlide ENDP
  965. ;────────────────────────────────────────────────────────────────────────────
  966. ; Effect 7 -- Tremolo
  967. ;────────────────────────────────────────────────────────────────────────────
  968. Go_Tremolo PROC NEAR
  969.     MOV    AL,[CMDLO+SI]
  970.     OR    AL,AL
  971.     JZ    SHORT Go_Tremolo2
  972.     MOV    BL,[TREMOLOCMD+SI]
  973.     AND    AL,0FH
  974.     JZ    SHORT Go_treskip
  975.     AND    BL,0F0H
  976.     OR    BL,AL
  977. Go_treskip:
  978.     MOV    AL,[CMDLO+SI]
  979.     AND    AL,0F0H
  980.     JZ    SHORT Go_treskip2
  981.     AND    BL,0FH
  982.     OR    BL,AL
  983. Go_treskip2:
  984.     MOV    [TREMOLOCMD+SI],BL
  985. Go_Tremolo2:
  986.     MOV    AL,[TREMOLOPOS+SI]
  987.     SHR    AL,2
  988.     AND    AX,1FH
  989.     MOV    BL,[WAVECONTROL+SI]
  990.     SHR    BL,4
  991.     AND    BL,3
  992.     JZ    SHORT Go_tre_sine
  993.     SHL    AL,3
  994.     CMP    BL,1
  995.     JE    SHORT Go_tre_rampdown
  996.     MOV    BL,255
  997.     JMP    SHORT Go_tre_set
  998. Go_tre_rampdown:
  999.     CMP    [TREMOLOPOS+SI],0
  1000.     JG    SHORT Go_tre_rampdown2
  1001.     MOV    BL,AL
  1002.     NOT    BL
  1003.     JMP    SHORT Go_tre_set
  1004. Go_tre_rampdown2:
  1005.     MOV    BL,AL
  1006.     JMP    SHORT Go_tre_set
  1007. Go_tre_sine:
  1008.     MOVZX    BX,AL
  1009.     MOV    BL,[MT_VIBRATOTABLE+BX]
  1010. Go_tre_set:
  1011.     MOV    AL,[TREMOLOCMD+SI]
  1012.     AND    AL,0FH
  1013.     MUL    BL
  1014.     MOV    BX,AX
  1015.     SHR    BX,6
  1016.     MOV    AL,[VOLUME+SI]
  1017.     CMP    [TREMOLOPOS+SI],0
  1018.     JG    SHORT Go_TremoloNeg        ; BMI  jns
  1019.     ADD    AL,BL
  1020.     JMP    SHORT Go_Tremolo3
  1021. Go_TremoloNeg:
  1022.     SUB    AL,BL
  1023. Go_Tremolo3:
  1024.     JNC    SHORT Go_TremoloSkip
  1025.     XOR    AX,AX
  1026. Go_TremoloSkip:
  1027.     CMP    AL,40H
  1028.     JBE    SHORT Go_TremoloOK        ; BLS
  1029.     MOV    AL,40H
  1030. Go_TremoloOK:
  1031.     MOV    [MVOL+SI],AL            ;was ah
  1032.     MOV    AL,[TREMOLOCMD+SI]
  1033.     AND    AL,0F0H
  1034.     SHR    AL,2
  1035.     ADD    [TREMOLOPOS+SI],AL
  1036.     RET
  1037. Go_Tremolo ENDP
  1038. ;────────────────────────────────────────────────────────────────────────────
  1039. ; Effect 9 -- Sample Offset
  1040. ;────────────────────────────────────────────────────────────────────────────
  1041. Go_SampleOffset PROC NEAR
  1042.     MOVZX    AX,[CMDLO+SI]
  1043.     OR    AL,AL
  1044.     JZ    SHORT Go_sononew
  1045.     MOV    [SAMPLEOFFSET+SI],AL
  1046. Go_sononew:
  1047.     MOVZX    AX,[SAMPLEOFFSET+SI]
  1048.     XCHG    AL,AH
  1049.     CMP    AX,[MMAXREP+DI]
  1050.     JAE    SHORT Go_sofskip
  1051.     MOV    [MOFS+DI],AX
  1052.     RET
  1053. Go_sofskip:
  1054.     MOV    AX,[MOFS+DI]
  1055.     MOV    [MMAXREP+DI],AX
  1056.     RET
  1057. Go_SampleOffset ENDP
  1058. ;────────────────────────────────────────────────────────────────────────────
  1059. ; Effect A -- Volume Slide
  1060. ;────────────────────────────────────────────────────────────────────────────
  1061. Go_VolumeSlide PROC NEAR
  1062.     MOV    AL,[CMDLO+SI]
  1063.     SHR    AL,4
  1064.     OR    AL,AL
  1065.     JZ    SHORT Go_VolSlideDown
  1066. Go_VolSlideUp:
  1067.     ADD    [VOLUME+SI],AL
  1068.     CMP    [VOLUME+SI],40H
  1069.     JBE    SHORT Go_vsdskip
  1070.     MOV    [VOLUME+SI],40H
  1071.     JMP    SHORT Go_vsdskip
  1072. Go_VolSlideDown:
  1073.     MOV    AL,[CMDLO+SI]
  1074.     AND    AL,0FH
  1075. Go_VolSlideDown2:
  1076.     SUB    [VOLUME+SI],AL
  1077.     JNC    SHORT Go_vsdskip
  1078.     MOV    [VOLUME+SI],0
  1079. Go_vsdskip:
  1080.     MOV    AL,[VOLUME+SI]
  1081.     MOV    [MVOL+SI],AL        ;was ah
  1082.     RET
  1083. Go_VolumeSlide ENDP
  1084. ;────────────────────────────────────────────────────────────────────────────
  1085. ; Effect B -- Position Jump
  1086. ;────────────────────────────────────────────────────────────────────────────
  1087. Go_PositionJump PROC NEAR
  1088.     MOV    AL,[CMDLO+SI]        ; Get where to jump
  1089.     DEC    AL            ; Update the
  1090.     MOV    MT_SONGPOS,AL        ; information.
  1091. Go_pj2:    MOV    MT_PBREAKPOS,0
  1092.     MOV    MT_POSJUMPFLAG,1
  1093.     RET
  1094. Go_PositionJump ENDP
  1095. ;────────────────────────────────────────────────────────────────────────────
  1096. ; Effect C -- Volume Change
  1097. ;────────────────────────────────────────────────────────────────────────────
  1098. Go_VolumeChange PROC NEAR
  1099.     MOV    AL,[CMDLO+SI]        ; Get value for volume
  1100.     CMP    AL,40H            ; Is it greater than 40h?
  1101.     JBE    SHORT Go_VolumeOK    ; Nope
  1102.     MOV    AL,40H
  1103. Go_VolumeOK:
  1104.     MOV    [VOLUME+SI],AL
  1105.     MOV    [MVOL+SI],AL        ;was ah
  1106.     RET
  1107. Go_VolumeChange ENDP
  1108. ;────────────────────────────────────────────────────────────────────────────
  1109. ; Effect D -- Pattern Break
  1110. ;────────────────────────────────────────────────────────────────────────────
  1111. Go_PatternBreak PROC NEAR
  1112.     MOV    AL,[CMDLO+SI]        ; Break to where?
  1113.     MOV    BL,AL            ; POSITION IS IN DECIMAL
  1114.     SHR    AL,4
  1115.     MOV    CL,10
  1116.     MUL    CL
  1117.     AND    BL,0FH
  1118.     ADD    AL,BL
  1119.     CMP    AL,63
  1120.     JG    Go_pj2
  1121.     MOV    MT_PBREAKPOS,AL
  1122.     MOV    MT_POSJUMPFLAG,1
  1123.     RET
  1124. Go_PatternBreak ENDP
  1125. ;────────────────────────────────────────────────────────────────────────────
  1126. ; Effect F -- Set Speed
  1127. ;────────────────────────────────────────────────────────────────────────────
  1128. Go_SetSpeed PROC NEAR
  1129.     MOV    AL,[CMDLO+SI]        ; Get value for speed
  1130.     OR    AL,AL
  1131.     JZ    Go_Return
  1132.     CMP    AL,32            ; Is it a BPM value ?
  1133.     JAE    SHORT Go_SetBPM
  1134.     MOV    MT_COUNTER,0
  1135.     MOV    MT_SPEED,AL
  1136.     RET
  1137. Go_SetBPM:
  1138.     MOVZX    CX,AL
  1139.     ADD    CX,100
  1140.     MOV    AX,4500
  1141.     XOR    DX,DX
  1142.     DIV    CX            ; NORMAL BPM SPEED IS 125
  1143.     MOV    BPM_SPEED,AL
  1144.     RET
  1145. Go_SetSpeed ENDP
  1146. ;=============================================================================
  1147. Go_CheckMoreEfx PROC NEAR
  1148.     MOVZX    BX,[CMD+SI]
  1149.     SHL    BL,1
  1150.     JMP    [Effect_Jump_Table2+BX]
  1151. Go_CheckMoreEfx ENDP
  1152. ;─────────────────────────────────────────────────────────────────────────────
  1153. ; Effect E
  1154. ;─────────────────────────────────────────────────────────────────────────────
  1155. Go_E_Commands PROC NEAR
  1156.     MOVZX    BX,[CMDLO+SI]
  1157.     SHR    BL,4
  1158.     SHL    BL,1
  1159.     MOV    AL,[CMDLO+SI]
  1160.     AND    AL,0FH
  1161.     JMP    [Effect_Jump_Table3+BX]
  1162. ;-----------------------------------------------------------------------------
  1163. ; Effect 0 -- FilterOnOff
  1164. ; Effect 1 -- Fine Porta Up
  1165. ;-----------------------------------------------------------------------------
  1166. Go_FinePortaUp:
  1167.     CMP    MT_COUNTER,0
  1168.     JNE    Go_Return
  1169.     MOV    MT_LOWMASK,0FH
  1170.     JMP    Go_PortaUp
  1171. ;-----------------------------------------------------------------------------
  1172. ; Effect 2 -- Fine Porta Down
  1173. ;-----------------------------------------------------------------------------
  1174. Go_FinePortaDown:
  1175.     CMP    MT_COUNTER,0
  1176.     JNE    Go_Return
  1177.     MOV    MT_LOWMASK,0FH
  1178.     JMP    Go_PortaDown
  1179. ;-----------------------------------------------------------------------------
  1180. ; Effect 3 -- Set Gliss Control
  1181. ;-----------------------------------------------------------------------------
  1182. Go_SetGlissControl:
  1183.     AND    [GLISSFUNK+SI],0F0H
  1184.     OR    [GLISSFUNK+SI],AL
  1185.     RET
  1186. ;-----------------------------------------------------------------------------
  1187. ; Effect 4 -- Set Vibrato Control
  1188. ;-----------------------------------------------------------------------------
  1189. Go_SetVibratoControl:
  1190.     AND    [WAVECONTROL+SI],0F0H
  1191.     OR    [WAVECONTROL+SI],AL
  1192.     RET
  1193. ;-----------------------------------------------------------------------------
  1194. ; Effect 5 -- Set Fine Tune
  1195. ;-----------------------------------------------------------------------------
  1196. Go_SetFineTune:
  1197.     MOV    [FINETUNE+SI],AL
  1198.     RET
  1199. ;-----------------------------------------------------------------------------
  1200. ; Effect 6 -- Jump Loop
  1201. ;-----------------------------------------------------------------------------
  1202. Go_JumpLoop:
  1203.     CMP    MT_COUNTER,0
  1204.     JNE    Go_Return
  1205.     OR    AL,AL
  1206.     JZ    SHORT Go_SetLoop
  1207.     CMP    [LOOPCOUNT+SI],0
  1208.     JE    SHORT Go_jumpcnt
  1209.     DEC    [LOOPCOUNT+SI]
  1210.     JZ    Go_Return
  1211. Go_jmploop:
  1212.     MOV    AL,[PATTPOS+SI]
  1213.     MOV    MT_PBREAKPOS,AL
  1214.     MOV    MT_PBREAKFLAG,1
  1215.     RET
  1216. Go_jumpcnt:
  1217.     MOV    [LOOPCOUNT+SI],AL
  1218.     JMP    Go_jmploop
  1219. Go_SetLoop:
  1220.     MOV    AX,MT_PATTERNPOS
  1221.     SHR    AX,2
  1222.     MOV    [PATTPOS+SI],AL
  1223.     RET
  1224. ;-----------------------------------------------------------------------------
  1225. ; Effect 7 -- Set Tremolo Control
  1226. ;-----------------------------------------------------------------------------
  1227. Go_SetTremoloControl:
  1228.     SHL    AL,4
  1229.     AND    [WAVECONTROL+SI],0FH
  1230.     OR    [WAVECONTROL+SI],AL
  1231.     RET
  1232. ;-----------------------------------------------------------------------------
  1233. ; Effect 9 -- Retrig Note
  1234. ;-----------------------------------------------------------------------------
  1235. Go_RetrigNote:
  1236.     MOV    BL,AL
  1237.     OR    BL,BL
  1238.     JZ    SHORT Go_rtnend
  1239.     MOVZX    AX,MT_COUNTER
  1240.     OR    AL,AL
  1241.     JNZ    SHORT Go_rtnskp
  1242.     CMP    [NOTE+DI],0
  1243.     JNE    SHORT Go_rtnskp
  1244.     MOV    MT_COUNTER,0
  1245. Go_rtnskp:
  1246.     DIV    BL
  1247.     XCHG    AL,AH
  1248.     OR    AL,AL
  1249.     JNZ    SHORT Go_rtnend
  1250. Go_DoRetrig:
  1251.     XOR    AX,AX
  1252.     MOV    [MOFS+DI],AX
  1253.     MOV    [MOFLOW+SI],AL
  1254.     MOV    AX,[LENGTHI+DI]
  1255.     MOV    [MMAXREP+DI],AX
  1256.     MOV    AX,[LOOPSTART+DI]
  1257.     MOV    [MREPEAT+DI],AX
  1258.     ADD    AX,[REPLEN+DI]
  1259.     MOV    [MREPLEN+DI],AX
  1260. Go_rtnend:
  1261.     RET
  1262. ;-----------------------------------------------------------------------------
  1263. ; Effect A -- Volume Fine Up
  1264. ;-----------------------------------------------------------------------------
  1265. Go_VolumeFineUp:
  1266.     CMP    MT_COUNTER,0
  1267.     JNE    Go_Return
  1268.     JMP    Go_VolSlideUp
  1269. ;-----------------------------------------------------------------------------
  1270. ; Effect B -- Volume Fine Down
  1271. ;-----------------------------------------------------------------------------
  1272. Go_VolumeFineDown:
  1273.     CMP    MT_COUNTER,0
  1274.     JNZ    Go_Return
  1275.     JMP    Go_VolSlideDown2
  1276. ;-----------------------------------------------------------------------------
  1277. ; Effect C -- Note Cut
  1278. ;-----------------------------------------------------------------------------
  1279. Go_NoteCut:
  1280.     CMP    AL,MT_COUNTER
  1281.     JNE    Go_Return
  1282.     MOV    [VOLUME+SI],0
  1283.     MOV    [MVOL+SI],AL
  1284.     RET
  1285. ;-----------------------------------------------------------------------------
  1286. ; Effect D -- Note Delay
  1287. ;-----------------------------------------------------------------------------
  1288. Go_NoteDelay:
  1289.     CMP    AL,MT_COUNTER
  1290.     JNE    Go_Return
  1291.     CMP    [NOTE+DI],0
  1292.     JE    Go_Return
  1293.     JMP    Go_DoRetrig
  1294. ;-----------------------------------------------------------------------------
  1295. ; Effect E -- Pattern Delay
  1296. ;-----------------------------------------------------------------------------
  1297. Go_PatternDelay:
  1298.     CMP    MT_COUNTER,0
  1299.     JNE    Go_Return
  1300.     CMP    MT_PATTDELAYTIME2,0
  1301.     JNZ    Go_Return
  1302.     INC    AL
  1303.     MOV    MT_PATTDELAYTIME,AL
  1304.     RET
  1305. ;-----------------------------------------------------------------------------
  1306. ; Effect F -- Funk It
  1307. ;-----------------------------------------------------------------------------
  1308. Go_E_Commands ENDP
  1309. ;=============================================================================
  1310.  
  1311.  
  1312. ;=============================================================================
  1313. MIXUP_CHANNELS PROC NEAR
  1314.     CMP    MOD_STAT,3        ;MOD HAS FINISHED
  1315.     JB    SHORT GMX7
  1316.     XOR    AX,AX
  1317.     XOR    BX,BX
  1318.     MOV    CX,MAX_CHAN_NUMB
  1319. LMX4:    MOV    [MSEG+BX],AX
  1320.     INC    BX
  1321.     INC    BX
  1322.     LOOP    LMX4
  1323. GMX7:    MOV    CX,DMA_CX
  1324.     CMP    MOD_STAT,2
  1325.     JB    SHORT GMX3
  1326.     OUT    0CH,AL            ;DMA FLIP-FLOP RESET
  1327.     MOVZX    DX,DMA_CHANNEL
  1328.     SHL    DL,1
  1329.     IN    AL,DX            ;GET DMA POSITION
  1330.     XCHG    AL,AH
  1331.     IN    AL,DX
  1332.     XCHG    AL,AH
  1333.     SUB    AX,DMA_POFF        ;AX IS OFFSET OF DMA-POS
  1334.     AND    AX,0FFFEH
  1335.     ADD    AX,DMA_MORE
  1336.     CMP    AX,DMA_MAX
  1337.     JB    SHORT GMX1
  1338.     SUB    AX,DMA_MAX
  1339. GMX1:    ADD    AX,DMA_OFFSET
  1340.     SUB    AX,DMA_PTR
  1341.     JNC    SHORT GMX2
  1342.     ADD    AX,DMA_MAX
  1343. GMX2:    MOV    CX,AX            ;CX IS NUMBER OF BYTES TO CALCULATE
  1344.     ADD    AX,DMA_PTR
  1345.     SUB    AX,DMA_OFFSET
  1346.     SUB    AX,2000H
  1347.     JC    SHORT GMX3
  1348.     SUB    CX,AX
  1349. GMX3:    XOR    BX,BX
  1350.     XOR    DI,DI
  1351.     CLD
  1352.     SHR    CX,1
  1353.     JZ    SHORT GMX5
  1354.     TEST    SBPRO_FLAG,1
  1355.     JNZ    SHORT SBPRO_MIXING    ;SB MONO-MIXING
  1356.     CALL    MIX_CHANNELA        ;INIT BUFFER WITH FIRST CHANNEL
  1357.     INC    BX
  1358.     INC    DI
  1359.     INC    DI
  1360.     DEC    CH_NUMB
  1361. LMX1:    CALL    MIX_CHANNELM        ;MIX CHANNELS
  1362.     INC    BX
  1363.     INC    DI
  1364.     INC    DI
  1365.     CMP    BX,CH_NUMB
  1366.     JB    LMX1
  1367.     INC    CH_NUMB
  1368.     CALL    MIX_CHANNELX        ;END UP BUFFER WITH LAST CHANNEL
  1369.     CALL    MIX_CHANNELS        ;SAMPLE1: MIDDLE CHANNEL
  1370. LMX2:    MOV    AX,DMA_NEWPTR        ;CHECK DMA-BUFFER OVERFLOW
  1371.     MOV    SI,DMA_MAX        ;ITS A RING BUFFER
  1372.     ADD    SI,DMA_OFFSET
  1373.     CMP    AX,SI
  1374.     JB    SHORT GMX4
  1375.     MOV    CX,AX
  1376.     MOV    DI,DMA_OFFSET
  1377.     SUB    CX,SI
  1378.     JZ    SHORT GMX6
  1379.     CLD
  1380.     SHR    CX,1
  1381.     PUSH    DS
  1382.     MOV    ES,DMA_SEG
  1383.     MOV    DS,DMA_SEG
  1384.     REP MOVSW            ;MOVE OVERFLOW DATA
  1385.     POP    DS
  1386. GMX6:    MOV    AX,DI
  1387. GMX4:    MOV    DMA_PTR,AX        ;START DSP OUTPUT
  1388.     CMP    MOD_STAT,1
  1389.     JNE    SHORT GMX5
  1390.     INC    MOD_STAT
  1391.     CALL    DSP_OUT
  1392. GMX5:    RET
  1393. SBPRO_MIXING:
  1394.     SHR    CX,1            ;SBPRO STEREO-MIXING
  1395.     JZ    GMX5
  1396.     MOV    AX,[STEREO_PANNING+DI]
  1397.     ADD    DMA_PTR,AX
  1398.     CALL    MIX_CHANNELA        ;INIT BUFFER WITH FIRST CHANNEL
  1399.     INC    BX
  1400.     INC    DI
  1401.     INC    DI
  1402.     MOV    AX,[STEREO_PANNING+DI]
  1403.     ADD    DMA_PTR,AX
  1404.     CALL    MIX_CHANNELA        ;THIS CHANNEL SHOULD BE ON RIGHT
  1405.     INC    BX            ;(OTHERWISE DMA_NEWPTR IS 2 TOO HIGH)
  1406.     INC    DI
  1407.     INC    DI
  1408. LMX3:    MOV    AX,[STEREO_PANNING+DI]
  1409.     ADD    DMA_PTR,AX
  1410.     CALL    MIX_CHANNELM        ;MIX CHANNELS
  1411.     INC    BX
  1412.     INC    DI
  1413.     INC    DI
  1414.     CMP    BX,CH_NUMB
  1415.     JB    LMX3
  1416.     MOV    AX,[STEREO_PANNING+DI]
  1417.     ADD    DMA_PTR,AX
  1418.     PUSH    CX
  1419.     CALL    MIX_CHANNELS1        ;SAMPLE1: LEFT CHANNEL
  1420.     POP    CX
  1421.     SUB    DMA_PTR,2
  1422.     PUSH    CX
  1423.     CALL    MIX_CHANNELS2        ;SAMPLE2: RIGHT CHANNEL
  1424.     POP    CX
  1425.     CALL    FIXUP_CHANNELS        ;END UP CHANNEL BY CONVERTING IT TO PC
  1426.     JMP    LMX2
  1427. MIXUP_CHANNELS ENDP
  1428. ;-----------------------------------------------------------------------------
  1429. MIX_CHANNELA PROC NEAR
  1430.     PUSH    CX BX DI
  1431.     MOV    SI,[MOFS+DI]        ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1432.     MOV    DX,[MFREQ+DI]        ;OFF ADD AFTER FIXED POINT (X/256)
  1433.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  1434.     MOV    DH,[MOFLOW+BX]        ;ACTUAL AFTER FIXED POINT VALUE
  1435.     MOV    AL,[MVOL+BX]        ;SAMPLE VOLUME
  1436.     MOV    BL,MUSIC_VOL        ;MASTER VOLUME
  1437.     MUL    BL
  1438.     XOR    AL,AL
  1439.     ADD    AX,MIXMUL_OFFSET
  1440.     MOV    BX,AX            ;DS:BX POINTS INTO MIXMUL_VOLUMETABLE
  1441.     MOV    ES,[MSEG+DI]
  1442.     MOV    AX,[MMAXREP+DI]        ;SP IS OFFSET OF SAMPLE ENDING
  1443.     MOV    WORD PTR SELFM1+2,AX
  1444.     MOV    WORD PTR SELFM2+2,AX
  1445.     MOV    AL,2
  1446. CLEAR_PENT_PREF1:
  1447.     DEC    AL            ;CLEAR ALSO PENTIUM PQ!!
  1448.     JNZ    CLEAR_PENT_PREF1
  1449.     JMP    SHORT CLEAR_PREF1    ;CLEAR PREFETCH QUEUE!!!
  1450. CLEAR_PREF1:
  1451.     MOV    DI,DMA_PTR
  1452.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1453.     MOV    AX,ES            ;ES:SI IS SAMPLE-DATA POINTER
  1454.     OR    AX,AX
  1455.     JZ    SHORT SILENT_FILLA
  1456. MIX_LOOPA:
  1457. SELFM1:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1458.     JAE    SHORT REST_FILLA
  1459.     MOV    AH,ES:[SI]
  1460.     ADD    DH,DL
  1461.     ADC    SI,BP
  1462. SELFM2:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1463.     JAE    SHORT REST_FILLA
  1464.     MOV    AL,ES:[SI]
  1465.     ADD    DH,DL
  1466.     ADC    SI,BP
  1467.     XLATB
  1468.     XCHG    AL,AH
  1469.     XLATB
  1470.     MOV    [DI],AX
  1471. SELFN1:    ADD    DI,2            ;SELFMODIFYING CODE
  1472.     LOOP    MIX_LOOPA
  1473. MIX_ENDA:
  1474.     MOV    AX,CS
  1475.     MOV    DS,AX
  1476.     MOV    AX,ES
  1477.     MOV    DMA_NEWPTR,DI
  1478.     POP    DI BX CX
  1479.     MOV    [MSEG+DI],AX
  1480.     MOV    [MOFLOW+BX],DH
  1481.     MOV    [MOFS+DI],SI
  1482.     RET
  1483. REST_FILLA:
  1484.     POP    SI
  1485.     PUSH    SI
  1486.     MOV    AX,CS:[MREPLEN+SI]
  1487.     OR    AX,AX
  1488.     JZ    SHORT SILENT_FILLA
  1489.     MOV    CS:[MMAXREP+SI],AX
  1490.     MOV    WORD PTR CS:SELFM1+2,AX
  1491.     MOV    WORD PTR CS:SELFM2+2,AX
  1492.     MOV    SI,CS:[MREPEAT+SI]
  1493.     JMP    MIX_LOOPA
  1494. SILENT_FILLA:
  1495.     MOV    BX,DS
  1496.     MOV    ES,BX
  1497.     TEST    CS:SBPRO_FLAG,1
  1498.     JNZ    SHORT SILENT_FILLB
  1499.     REP STOSW
  1500.     MOV    ES,AX
  1501.     JMP    MIX_ENDA
  1502. SILENT_FILLB:
  1503.     STOSW
  1504.     INC    DI
  1505.     INC    DI
  1506.     LOOP    SILENT_FILLB
  1507.     MOV    ES,AX
  1508.     JMP    MIX_ENDA
  1509. MIX_CHANNELA ENDP
  1510. ;-----------------------------------------------------------------------------
  1511. MIX_CHANNELM PROC NEAR
  1512.     PUSH    CX BX DI
  1513.     MOV    SI,[MOFS+DI]        ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1514.     MOV    DX,[MFREQ+DI]        ;OFF ADD AFTER FIXED POINT (X/256)
  1515.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  1516.     MOV    DH,[MOFLOW+BX]        ;ACTUAL AFTER FIXED POINT VALUE
  1517.     MOV    AL,[MVOL+BX]        ;SAMPLE VOLUME
  1518.     MOV    BL,MUSIC_VOL        ;MASTER VOLUME
  1519.     MUL    BL
  1520.     XOR    AL,AL
  1521.     ADD    AX,MIXMUL_OFFSET
  1522.     MOV    BX,AX            ;DS:BX POINTS INTO MIXMUL_VOLUMETABLE
  1523.     MOV    ES,[MSEG+DI]
  1524.     MOV    AX,[MMAXREP+DI]        ;OFFSET OF SAMPLE ENDING
  1525.     MOV    WORD PTR SELFM3+2,AX
  1526.     MOV    WORD PTR SELFM4+2,AX
  1527.     MOV    AL,2
  1528. CLEAR_PENT_PREF2:
  1529.     DEC    AL            ;CLEAR ALSO PENTIUM PQ!!
  1530.     JNZ    CLEAR_PENT_PREF2
  1531.     JMP    SHORT CLEAR_PREF2    ;CLEAR PREFETCH QUEUE!!!
  1532. CLEAR_PREF2:
  1533.     MOV    DI,DMA_PTR
  1534.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1535.     MOV    AX,ES
  1536.     OR    AX,AX
  1537.     JZ    SHORT MIX_ENDM
  1538. MIX_LOOPM:
  1539. SELFM3:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1540.     JAE    SHORT REST_FILLM
  1541.     MOV    AH,ES:[SI]
  1542.     ADD    DH,DL
  1543.     ADC    SI,BP
  1544. SELFM4:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1545.     JAE    SHORT REST_FILLM
  1546.     MOV    AL,ES:[SI]
  1547.     ADD    DH,DL
  1548.     ADC    SI,BP
  1549.     XLATB
  1550.     XCHG    AL,AH
  1551.     XLATB
  1552.     ADD    [DI],AX
  1553. SELFN2:    ADD    DI,2            ;SELFMODIFYING CODE
  1554.     LOOP    MIX_LOOPM
  1555. MIX_ENDM:
  1556.     MOV    AX,CS
  1557.     MOV    DS,AX
  1558.     MOV    AX,ES
  1559.     POP    DI BX CX
  1560.     MOV    [MSEG+DI],AX
  1561.     MOV    [MOFLOW+BX],DH
  1562.     MOV    [MOFS+DI],SI
  1563.     RET
  1564. REST_FILLM:
  1565.     POP    SI
  1566.     PUSH    SI
  1567.     MOV    AX,CS:[MREPLEN+SI]
  1568.     OR    AX,AX
  1569.     JZ    SHORT SILENT_FILLM
  1570.     MOV    CS:[MMAXREP+SI],AX
  1571.     MOV    WORD PTR CS:SELFM3+2,AX
  1572.     MOV    WORD PTR CS:SELFM4+2,AX
  1573.     MOV    SI,CS:[MREPEAT+SI]
  1574.     JMP    MIX_LOOPM
  1575. SILENT_FILLM:
  1576.     MOV    ES,AX
  1577.     JMP    MIX_ENDM
  1578. MIX_CHANNELM ENDP
  1579. ;-----------------------------------------------------------------------------
  1580. MIX_CHANNELX PROC NEAR
  1581.     PUSH    CX BX DI
  1582.     MOV    SI,[MOFS+DI]        ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1583.     MOV    DX,[MFREQ+DI]        ;OFF ADD AFTER FIXED POINT (X/256)
  1584.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  1585.     MOV    DH,[MOFLOW+BX]        ;ACTUAL AFTER FIXED POINT VALUE
  1586.     MOV    AL,[MVOL+BX]        ;SAMPLE VOLUME
  1587.     MOV    BL,MUSIC_VOL        ;MASTER VOLUME
  1588.     MUL    BL
  1589.     XOR    AL,AL
  1590.     ADD    AX,MIXMUL_OFFSET
  1591.     MOV    BX,AX            ;DS:BX POINTS INTO MIXMUL_VOLUMETABLE
  1592.     MOV    ES,[MSEG+DI]
  1593.     MOV    AX,[MMAXREP+DI]        ;SP IS OFFSET OF SAMPLE ENDING
  1594.     MOV    WORD PTR SELFM5+2,AX
  1595.     MOV    WORD PTR SELFM6+2,AX
  1596.     MOV    WORD PTR SELFM7+2,8080H
  1597.     CMP    SAM_SEG1,0
  1598.     JE    SHORT NO_SAMPLES
  1599.     MOV    WORD PTR SELFM7+2,0
  1600. NO_SAMPLES:
  1601.     MOV    AL,2
  1602. CLEAR_PENT_PREF3:
  1603.     DEC    AL            ;CLEAR ALSO PENTIUM PQ!!
  1604.     JNZ    CLEAR_PENT_PREF3
  1605.     JMP    SHORT CLEAR_PREF3    ;CLEAR PREFETCH QUEUE!!!
  1606. CLEAR_PREF3:
  1607.     MOV    DI,DMA_PTR
  1608.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1609.     MOV    AX,ES            ;ES:SI IS SAMPLE-DATA POINTER
  1610.     OR    AX,AX
  1611.     JZ    SHORT SILENT_FILLX
  1612. MIX_LOOPX:
  1613. SELFM5:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1614.     JAE    SHORT REST_FILLX
  1615.     MOV    AH,ES:[SI]
  1616.     ADD    DH,DL
  1617.     ADC    SI,BP
  1618. SELFM6:    CMP    SI,0FFFFH        ;SELFMODIFYING CODE
  1619.     JAE    SHORT REST_FILLX
  1620.     MOV    AL,ES:[SI]
  1621.     ADD    DH,DL
  1622.     ADC    SI,BP
  1623.     XLATB
  1624.     XCHG    AL,AH
  1625.     XLATB
  1626.     ADD    [DI],AX
  1627. SELFM7:    XOR    WORD PTR [DI],8080H
  1628.     INC    DI
  1629.     INC    DI
  1630.     LOOP    MIX_LOOPX
  1631. MIX_ENDX:
  1632.     MOV    AX,CS
  1633.     MOV    DS,AX
  1634.     MOV    AX,ES
  1635.     POP    DI BX CX
  1636.     MOV    [MSEG+DI],AX
  1637.     MOV    [MOFLOW+BX],DH
  1638.     MOV    [MOFS+DI],SI
  1639.     RET
  1640. REST_FILLX:
  1641.     POP    SI
  1642.     PUSH    SI
  1643.     MOV    AX,CS:[MREPLEN+SI]
  1644.     OR    AX,AX
  1645.     JZ    SHORT SILENT_FILLX
  1646.     MOV    CS:[MMAXREP+SI],AX
  1647.     MOV    WORD PTR CS:SELFM5+2,AX
  1648.     MOV    WORD PTR CS:SELFM6+2,AX
  1649.     MOV    SI,CS:[MREPEAT+SI]
  1650.     JMP    MIX_LOOPX
  1651. SILENT_FILLX:
  1652.     MOV    ES,AX
  1653.     CMP    CS:[SAM_SEG1],0
  1654.     JNE    MIX_ENDX
  1655. SILENT_FILLL:
  1656.     XOR    WORD PTR [DI],8080H
  1657.     INC    DI
  1658.     INC    DI
  1659.     LOOP    SILENT_FILLL
  1660.     JMP    MIX_ENDX
  1661. MIX_CHANNELX ENDP
  1662. ;-----------------------------------------------------------------------------
  1663. FIXUP_CHANNELS PROC NEAR
  1664.     MOV    DI,DMA_PTR
  1665.     MOV    DS,DMA_SEG
  1666. FIXUP_LOOP:
  1667.     XOR    DWORD PTR [DI],80808080H
  1668.     INC    DI
  1669.     ROL    WORD PTR [DI],8
  1670.     ADD    DI,3
  1671.     LOOP    FIXUP_LOOP
  1672.     MOV    AX,CS
  1673.     MOV    DS,AX
  1674.     RET
  1675. FIXUP_CHANNELS ENDP
  1676. ;-----------------------------------------------------------------------------
  1677. MIX_CHANNELS PROC NEAR
  1678.     CMP    SAM_SEG1,0
  1679.     JE    SHORT GO_BACKS
  1680.     CALL    EMS_SAVE
  1681.     PUSH    EAX
  1682.     MOV    EAX,SAM_OFS1
  1683.     CALL    EMS_PAGING
  1684.     POP    EAX
  1685.     MOV    SI,DI            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1686.     MOV    DX,SAM_FRQ1        ;OFF ADD AFTER FIXED POINT (X/256)
  1687.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  1688.     MOV    DH,SAM_OFL1        ;ACTUAL AFTER FIXED POINT VALUE
  1689.     MOV    BX,SAM_MAX1        ;COUNTER FOR SAMPLE ENDING
  1690.     MOV    DI,DMA_PTR
  1691.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1692.     PUSH    SI
  1693. MIX_LOOPS:
  1694.     MOV    AL,ES:[SI]
  1695.     ADD    DH,DL
  1696.     ADC    SI,BP
  1697.     SUB    DH,DL
  1698.     ADD    DH,DL
  1699.     SBB    BX,BP
  1700.     JC    SHORT REST_FILLS
  1701.     JZ    SHORT REST_FILLS
  1702.     SAR    BYTE PTR [DI],1
  1703.     MOV    AH,ES:[SI]
  1704.     SAR    BYTE PTR [DI+1],1
  1705.     ADD    DH,DL
  1706.     ADC    SI,BP
  1707.     ADD    [DI],AX
  1708.     XOR    WORD PTR [DI],8080H
  1709.     INC    DI
  1710.     INC    DI
  1711.     SUB    DH,DL
  1712.     ADD    DH,DL
  1713.     SBB    BX,BP
  1714.     JC    SHORT REST_FILLS
  1715.     JZ    SHORT REST_FILLS
  1716.     LOOP    MIX_LOOPS
  1717. MIX_ENDS:
  1718.     MOV    AX,CS
  1719.     MOV    DS,AX
  1720.     MOV    SAM_OFL1,DH
  1721.     POP    AX
  1722.     SUB    SI,AX
  1723.     PUSH    EAX
  1724.     MOVZX    EAX,SI
  1725.     ADD    SAM_OFS1,EAX
  1726.     POP    EAX
  1727.     MOV    SAM_MAX1,BX
  1728.     CALL    EMS_RESTORE
  1729. GO_BACKS:
  1730.     RET
  1731. REST_FILLS:
  1732.     MOV    CS:SAM_SEG1,0
  1733. SILENT_FILLS:
  1734.     XOR    WORD PTR [DI],8080H
  1735.     INC    DI
  1736.     INC    DI
  1737.     LOOP    SILENT_FILLS
  1738.     JMP    MIX_ENDS
  1739. MIX_CHANNELS ENDP
  1740. ;-----------------------------------------------------------------------------
  1741. MIX_CHANNELS1 PROC NEAR
  1742.     CMP    SAM_SEG1,0
  1743.     JE    SHORT GO_BACKS1
  1744.     CALL    EMS_SAVE
  1745.     PUSH    EAX
  1746.     MOV    EAX,SAM_OFS1
  1747.     CALL    EMS_PAGING
  1748.     POP    EAX
  1749.     MOV    SI,DI            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1750.     MOV    DX,SAM_FRQ1        ;OFF ADD AFTER FIXED POINT (X/256)
  1751.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  1752.     MOV    DH,SAM_OFL1        ;ACTUAL AFTER FIXED POINT VALUE
  1753.     MOV    BX,SAM_MAX1        ;COUNTER FOR SAMPLE ENDING
  1754.     MOV    DI,DMA_PTR
  1755.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1756.     PUSH    SI
  1757. MIX_LOOPS1:
  1758.     MOV    AL,ES:[SI]
  1759.     ADD    DH,DL
  1760.     ADC    SI,BP
  1761.     SUB    DH,DL
  1762.     ADD    DH,DL
  1763.     SBB    BX,BP
  1764.     JC    SHORT MIX_ENDS1
  1765.     JZ    SHORT MIX_ENDS1
  1766.     SAR    BYTE PTR [DI],1
  1767.     MOV    AH,ES:[SI]
  1768.     SAR    BYTE PTR [DI+1],1
  1769.     ADD    DH,DL
  1770.     ADC    SI,BP
  1771.     ADD    [DI],AX
  1772.     ADD    DI,4
  1773.     SUB    DH,DL
  1774.     ADD    DH,DL
  1775.     SBB    BX,BP
  1776.     JC    SHORT MIX_ENDS1
  1777.     JZ    SHORT MIX_ENDS1
  1778.     LOOP    MIX_LOOPS1
  1779. MIX_REST1:
  1780.     MOV    AX,CS
  1781.     MOV    DS,AX
  1782.     MOV    SAM_OFL1,DH
  1783.     POP    AX
  1784.     SUB    SI,AX
  1785.     PUSH    EAX
  1786.     MOVZX    EAX,SI
  1787.     ADD    SAM_OFS1,EAX
  1788.     POP    EAX
  1789.     MOV    SAM_MAX1,BX
  1790.     CALL    EMS_RESTORE
  1791. GO_BACKS1:
  1792.     RET
  1793. MIX_ENDS1:
  1794.     MOV    CS:SAM_SEG1,0
  1795.     JMP    MIX_REST1
  1796. MIX_CHANNELS1 ENDP
  1797. ;-----------------------------------------------------------------------------
  1798. MIX_CHANNELS2 PROC NEAR
  1799.     CMP    SAM_SEG2,0
  1800.     JE    SHORT GO_BACKS2
  1801.     CALL    EMS_SAVE
  1802.     PUSH    EAX
  1803.     MOV    EAX,SAM_OFS2
  1804.     CALL    EMS_PAGING
  1805.     POP    EAX
  1806.     MOV    SI,DI            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1807.     MOV    DX,SAM_FRQ2        ;OFF ADD AFTER FIXED POINT (X/256)
  1808.     MOVZX    BP,DH            ;OFF ADD BEFORE FIXED POINT
  1809.     MOV    DH,SAM_OFL2        ;ACTUAL AFTER FIXED POINT VALUE
  1810.     MOV    BX,SAM_MAX2        ;COUNTER FOR SAMPLE ENDING
  1811.     MOV    DI,DMA_PTR
  1812.     MOV    DS,DMA_SEG        ;DS:DI IS DMA-BUFFER POINTER
  1813.     PUSH    SI
  1814. MIX_LOOPS2:
  1815.     MOV    AL,ES:[SI]
  1816.     ADD    DH,DL
  1817.     ADC    SI,BP
  1818.     SUB    DH,DL
  1819.     ADD    DH,DL
  1820.     SBB    BX,BP
  1821.     JC    SHORT MIX_ENDS2
  1822.     JZ    SHORT MIX_ENDS2
  1823.     SAR    BYTE PTR [DI],1
  1824.     MOV    AH,ES:[SI]
  1825.     SAR    BYTE PTR [DI+1],1
  1826.     ADD    DH,DL
  1827.     ADC    SI,BP
  1828.     ADD    [DI],AX
  1829.     ADD    DI,4
  1830.     SUB    DH,DL
  1831.     ADD    DH,DL
  1832.     SBB    BX,BP
  1833.     JC    SHORT MIX_ENDS2
  1834.     JZ    SHORT MIX_ENDS2
  1835.     LOOP    MIX_LOOPS2
  1836. MIX_REST2:
  1837.     MOV    AX,CS
  1838.     MOV    DS,AX
  1839.     MOV    SAM_OFL2,DH
  1840.     POP    AX
  1841.     SUB    SI,AX
  1842.     PUSH    EAX
  1843.     MOVZX    EAX,SI
  1844.     ADD    SAM_OFS2,EAX
  1845.     POP    EAX
  1846.     MOV    SAM_MAX2,BX
  1847.     CALL    EMS_RESTORE
  1848. GO_BACKS2:
  1849.     RET
  1850. MIX_ENDS2:
  1851.     MOV    CS:SAM_SEG2,0
  1852.     JMP    MIX_REST2
  1853. MIX_CHANNELS2 ENDP
  1854. ;-----------------------------------------------------------------------------
  1855. ; SET EMS-PAGES
  1856. ; IN:  EAX= EMS-OFFSET
  1857. ; OUT: ES:DI= SEGMENT & OFFSET IN EMS PAGE
  1858. ;-----------------------------------------------------------------------------
  1859. EMS_PAGING PROC NEAR
  1860.     MOV    DI,AX
  1861.     AND    DI,3FFFH
  1862.     MOV    ES,EMS_SEG
  1863.     PUSHA
  1864.     PUSH    EAX
  1865.     SHR    EAX,14
  1866.     MOV    BX,AX
  1867.     XOR    AL,AL
  1868.     MOV    DX,EMS_HANDLE
  1869.     MOV    AH,44H
  1870.     INT    67H
  1871.     INC    AL
  1872.     INC    BX
  1873.     MOV    AH,44H
  1874.     INT    67H
  1875.     INC    AL
  1876.     INC    BX
  1877.     MOV    AH,44H
  1878.     INT    67H
  1879.     INC    AL
  1880.     INC    BX
  1881.     MOV    AH,44H
  1882.     INT    67H
  1883.     POP    EAX
  1884.     POPA
  1885.     RET
  1886. EMS_PAGING ENDP
  1887. ;-----------------------------------------------------------------------------
  1888. EMS_SAVE PROC NEAR
  1889.     PUSH    AX DX
  1890.     MOV    DX,EMS_HANDLE        ;EMS MAPPING SAVE
  1891.     MOV    AH,47H
  1892.     INT    67H
  1893.     POP    DX AX
  1894.     RET
  1895. EMS_SAVE ENDP
  1896. ;-----------------------------------------------------------------------------
  1897. EMS_RESTORE PROC NEAR
  1898.     PUSH    AX DX
  1899.     MOV    DX,EMS_HANDLE        ;EMS MAPPING RESTORE
  1900.     MOV    AH,48H
  1901.     INT    67H
  1902.     POP    DX AX
  1903.     RET
  1904. EMS_RESTORE ENDP
  1905. ;╒═══════════════════════════════════════════════════════════════════════════╕
  1906. ;│ DESCRIPTION: Calculates the values for the mixing multiplication table.   │
  1907. ;│              This table is used during 4/8-channel mixing to speed up the │
  1908. ;│              operation by avoiding 'mul' instructions.                    │
  1909. ;╘═══════════════════════════════════════════════════════════════════════════╛
  1910. MAKE_MIXMUL_VOLUMETABLE PROC NEAR
  1911.     MOV    ES,DMA_SEG
  1912.     MOV    DI,MIXMUL_OFFSET
  1913.     CLD
  1914.     MOV    CX,CH_NUMB
  1915.     SHR    CL,3
  1916.     MOV    CH,SBPRO_FLAG
  1917.     XOR    BX,BX            ; start with volume 0
  1918.     INC    BH
  1919. VOLUMELOOP:                ; start with sample 0
  1920. SAMPLELOOP:
  1921.     MOV    AL,BL
  1922.     XCHG    CL,CH
  1923.     IMUL    BH
  1924.     OR    AH,AH            ; ROUND UP
  1925.     JNS    SHORT GMK1
  1926.     OR    AL,AL
  1927.     JZ    SHORT GMK1
  1928.     INC    AH
  1929. GMK1:    SAL    AX,CL
  1930.     XCHG    CL,CH
  1931.     MOV    AL,AH
  1932.     SAR    AL,CL            ; 8- CHANNEL MIXING
  1933.     STOSB
  1934.     INC    BL
  1935.     JNZ    SAMPLELOOP
  1936.     INC    BH
  1937.     CMP    BH,64
  1938.     JBE    VOLUMELOOP
  1939.     RET
  1940. MAKE_MIXMUL_VOLUMETABLE ENDP
  1941. ;=============================================================================
  1942.  
  1943.  
  1944. ;=============================================================================
  1945. ;
  1946. ; DOS ROUTINES
  1947. ;
  1948. ;=============================================================================
  1949. ;-----------------------------------------------------------------------------
  1950. ; TIMER-IRQ-HANDLER: 1024 HZ CALLING FREQUENCE
  1951. ;-----------------------------------------------------------------------------
  1952. TIMER_HANDLER PROC FAR
  1953.     PUSH    AX
  1954.     CMP    CS:SYSTEM,0
  1955.     JNE    SHORT WT6
  1956.     MOV    AL,UHR_STATC
  1957.     OUT    UHR_INDEX,AL
  1958.     JMP    SHORT WT1
  1959. WT1:    JMP    SHORT WT2
  1960. WT2:    IN    AL,UHR_PORT
  1961. WT6:    MOV     AL,20H
  1962.     OUT     IRQ3,AL
  1963.     OUT    IRQ1,AL
  1964.     CMP    CS:MOD_STAT,0
  1965.     JE    SHORT WT3
  1966.     DEC    CS:BPM_COUNT        ;1024/20= 50 HZ
  1967.     JNZ    SHORT WT3
  1968.     STI
  1969.     PUSHA
  1970.     PUSH    DS ES CS
  1971.     POP    DS
  1972.     MOV    AL,BPM_SPEED
  1973.     MOV    BPM_COUNT,AL
  1974.     CALL    CONTROL_CHANNELS
  1975.     CALL    MIXUP_CHANNELS
  1976.     TEST    SB_MODUS,2
  1977.     JZ    SHORT WT5
  1978.     MOV    MOD_STAT,4
  1979.     JMP    SHORT WT4
  1980. WT5:    CMP    MOD_STAT,4
  1981.     JB    SHORT WT4
  1982.     MOV    MOD_STAT,2
  1983. WT4:    POP    ES DS
  1984.     POPA
  1985. WT3:    POP    AX
  1986.     CMP    CS:SYSTEM,0
  1987.     JE    SHORT WT7
  1988.     DEC    CS:IRQCOUNT
  1989.     JNZ    SHORT WT7
  1990.     MOV    CS:IRQCOUNT,56
  1991.     JMP    DWORD PTR CS:[HOLD70]
  1992. WT7:    IRET
  1993. TIMER_HANDLER ENDP
  1994. ;-----------------------------------------------------------------------------
  1995. ; SOUNDBLASTER-IRQ-HANDLER
  1996. ;-----------------------------------------------------------------------------
  1997. SBIRQ_HANDLER PROC FAR
  1998.     PUSH    AX CX DX
  1999.     MOV    DX,CS:SB_RSTAT        ;CLEAR IRQ
  2000.     IN    AL,DX
  2001.     DEC    DX
  2002.     DEC    DX
  2003.     MOV    CX,1000H
  2004. WUV1:    IN    AL,DX
  2005.     OR    AL,AL
  2006.     JNS    SHORT WUW1
  2007.     LOOP    WUV1
  2008. WUW1:    CMP    CS:SBPRO_FLAG,1
  2009.     JE    SHORT WUV4
  2010.     MOV    AL,14H            ;SB MONO
  2011.     OUT    DX,AL
  2012.     MOV    CX,1000H
  2013. WUV2:    IN    AL,DX            ;WAIT UNTIL READY
  2014.     OR    AL,AL
  2015.     JNS    SHORT WUW2
  2016.     LOOP    WUV2
  2017. WUW2:    MOV    AL,0FFH            ;SET MAX BLOCK SIZE
  2018.     OUT    DX,AL
  2019.     MOV    CX,1000H
  2020. WUV3:    IN    AL,DX            ;WAIT UNTIL READY
  2021.     OR    AL,AL
  2022.     JNS    SHORT WUW3
  2023.     LOOP    WUV3
  2024. WUW3:    MOV    AL,0FFH
  2025.     OUT    DX,AL
  2026.     MOV    AL,20H
  2027.     OUT    IRQ1,AL
  2028.     POP    DX CX AX
  2029.     IRET
  2030. WUV4:    MOV    AL,48H            ;SB STEREO
  2031.     OUT    DX,AL
  2032.     MOV    CX,1000H
  2033. WUV5:    IN    AL,DX            ;WAIT UNTIL READY
  2034.     OR    AL,AL
  2035.     JNS    SHORT WUW5
  2036.     LOOP    WUV5
  2037. WUW5:    MOV    AL,0FFH            ;SET MAX BLOCK SIZE
  2038.     OUT    DX,AL
  2039.     MOV    CX,1000H
  2040. WUV6:    IN    AL,DX            ;WAIT UNTIL READY
  2041.     OR    AL,AL
  2042.     JNS    SHORT WUW6
  2043.     LOOP    WUV6
  2044. WUW6:    MOV    AL,0FFH
  2045.     OUT    DX,AL
  2046.     MOV    CX,1000H
  2047. WUV7:    IN    AL,DX            ;WAIT UNTIL READY
  2048.     OR    AL,AL
  2049.     JNS    SHORT WUW7
  2050.     LOOP    WUV7
  2051. WUW7:    MOV    AL,91H            ;START SBPRO
  2052.     OUT    DX,AL
  2053.     MOV    AL,20H
  2054.     OUT    IRQ1,AL
  2055.     POP    DX CX AX
  2056.     IRET
  2057. SBIRQ_HANDLER ENDP
  2058. ;-----------------------------------------------------------------------------
  2059. ; SERVICE IRQ SWAPPING; USES THE REAL-TIME-CLOCK OR TIMER IRQ
  2060. ;-----------------------------------------------------------------------------
  2061. IRQ_INIT PROC NEAR
  2062.     CLI
  2063.     XOR     AX,AX
  2064.     MOV     ES,AX
  2065.     CMP    SYSTEM,0
  2066.     JNE    WU11
  2067.     MOV     AX,COMP_SPEED2        ;XCHANGE INIT & STOP DATA FOR DOS
  2068.     MOV     DX,COMP_SPEED3
  2069.     MOV     COMP_SPEED2,DX
  2070.     MOV     COMP_SPEED3,AX
  2071.     MOV    AL,UHR_STATA        ;SET CLOCK-IRQ-RATE (1024 HZ)
  2072.     OUT    UHR_INDEX,AL
  2073.     JMP    SHORT WU1
  2074. WU1:    JMP    SHORT WU2
  2075. WU2:    XCHG    AL,AH
  2076.     IN    AL,UHR_PORT
  2077.     AND    AL,0F0H
  2078.     OR    AL,DL
  2079.     XCHG    AL,AH
  2080.     OUT    UHR_INDEX,AL
  2081.     JMP    SHORT WU3
  2082. WU3:    JMP    SHORT WU4
  2083. WU4:    XCHG    AL,AH
  2084.     OUT    UHR_PORT,AL
  2085.     JMP    SHORT WU5
  2086. WU5:    JMP    SHORT WU6
  2087. WU6:    MOV    AL,UHR_STATB        ;SET CLOCK-IRQ-MODUS
  2088.     OUT    UHR_INDEX,AL
  2089.     JMP    SHORT WU7
  2090. WU7:    JMP    SHORT WU8
  2091. WU8:    XCHG    AL,AH
  2092.     IN    AL,UHR_PORT
  2093.     AND    AL,08FH
  2094.     MOV    DL,DH
  2095.     AND    DL,40H
  2096.     OR    AL,DL
  2097.     XCHG    AL,AH
  2098.     OUT    UHR_INDEX,AL
  2099.     JMP    SHORT WU9
  2100. WU9:    JMP    SHORT WU10
  2101. WU10:    XCHG    AL,AH
  2102.     OUT    UHR_PORT,AL
  2103.     IN    AL,IRQ4            ;IRQ8 DE-/MASK
  2104.     AND    AL,0FEH
  2105.     MOV    DL,DH
  2106.     AND    DL,1
  2107.     OR    AL,DL
  2108.     OUT    IRQ4,AL
  2109.     IN    AL,IRQ2            ;SBIRQ DE-/MASK
  2110.     MOV    CL,IRQ_NUMBER
  2111.     SHL    DL,CL
  2112.     MOV    DH,0FEH
  2113.     ROL    DH,CL
  2114.     AND    AL,DH
  2115.     OR    AL,DL
  2116.     OUT    IRQ2,AL
  2117.     MOV     BX,4*70H                ;CLOCK-IRQ DETOUR
  2118.     MOV     EAX,ES:[BX]
  2119.     MOV     EDX,HOLD70
  2120.     MOV     ES:[BX],EDX
  2121.     MOV     HOLD70,EAX
  2122.     JMP    WU12
  2123. WU11:    MOV     AX,COMP_SPEED4        ;FOR WINDOWS
  2124.     MOV     DX,COMP_SPEED5
  2125.     MOV     COMP_SPEED4,DX
  2126.     MOV     COMP_SPEED5,AX
  2127.     MOV     AL,00110110B            ;SET TIMER0 TO 1.024 KHZ
  2128.     OUT     PIT1,AL                 ;DIVIDER =1193
  2129.     MOV     AL,DL
  2130.     OUT     TIMER0,AL
  2131.     JMP     SHORT OUT40
  2132. OUT40:  MOV     AL,DH
  2133.     OUT     TIMER0,AL
  2134.     MOV     AX,COMP_SPEED2        ;XCHANGE INIT & STOP DATA FOR DOS
  2135.     MOV     DX,COMP_SPEED3
  2136.     MOV     COMP_SPEED2,DX
  2137.     MOV     COMP_SPEED3,AX
  2138.     IN    AL,IRQ2            ;SBIRQ DE-/MASK
  2139.     MOV    CL,IRQ_NUMBER
  2140.     SHL    DL,CL
  2141.     MOV    DH,0FEH
  2142.     ROL    DH,CL
  2143.     AND    AL,DH
  2144.     OR    AL,DL
  2145.     OUT    IRQ2,AL
  2146.     MOV     BX,4*8H                 ;TIMEOUT-IRQ DETOUR
  2147.     MOV     EAX,ES:[BX]
  2148.     MOV     EDX,HOLD70
  2149.     MOV     ES:[BX],EDX
  2150.     MOV     HOLD70,EAX
  2151. WU12:    MOV     BL,CL            ;SOUNDBLASTER-IRQ DETOUR
  2152.     ADD    BL,8
  2153.     SHL    BL,2
  2154.     XOR    BH,BH
  2155.     MOV     EAX,ES:[BX]
  2156.     MOV     EDX,HOLDSB
  2157.     MOV     ES:[BX],EDX
  2158.     MOV     HOLDSB,EAX
  2159.     MOV    AL,20H
  2160.     OUT    IRQ3,AL
  2161.     OUT    IRQ1,AL
  2162.     STI
  2163.     RET
  2164. IRQ_INIT ENDP
  2165. ;----------------------------------------------------------------------------
  2166. ; ALLOCATES MEMORY FOR TRACKS, CARRY-FLAG 0=OK 1=ABBRUCH
  2167. ;----------------------------------------------------------------------------
  2168. SET_TMEM PROC NEAR
  2169.     MOV     AH,48H
  2170.     MOV     BX,1000H                ;64K TRACK BUFFER (WILL BE RESIZED)
  2171.     INT     21H
  2172.     JC      SHORT STCM1
  2173.     MOV     TRACK_SEG,AX
  2174.     MOV    AH,48H
  2175.     MOV    BX,80H            ;2K PATTERN BUFFER
  2176.     INT    21H
  2177.     JC    SHORT STCM1
  2178.     MOV    PATTERN_SEG,AX
  2179. STCM1:  RET
  2180. SET_TMEM ENDP
  2181. ;----------------------------------------------------------------------------
  2182. ; DEALLOCATES MEMORY OF TRACKS
  2183. ;----------------------------------------------------------------------------
  2184. FREE_TMEM PROC NEAR
  2185.     MOV    AX,SAMPLE_SEG
  2186.     MOV    ES,AX
  2187.     MOV    AH,49H
  2188.     INT    21H
  2189.     MOV     AX,TRACK_SEG
  2190.     MOV     ES,AX
  2191.     MOV     AH,49H
  2192.     INT     21H
  2193.     RET
  2194. FREE_TMEM ENDP
  2195. ;----------------------------------------------------------------------------
  2196. ; ALLOCATES MEMORY OF DMA_BUFFER & MIXMUL_TABLE, CARRY 0=OK 1=ERROR
  2197. ;----------------------------------------------------------------------------
  2198. SET_DMEM PROC NEAR
  2199.     MOV     AH,48H
  2200.     MOV     BX,0600H                ;24K BUFFER
  2201.     INT     21H
  2202.     JC      SHORT SDCM1
  2203.     MOV     DMA_SEG,AX
  2204.     MOV    DMA_OFFSET,0        ;DMA_BUFFER CA.  8K
  2205.     MOV    MIXMUL_OFFSET,2000H    ;MIXMUL_TAB CA. 16K
  2206.     AND    AX,0FFFH        ;CHECK FOR 64K DMA PAGE
  2207.     CMP    AX,0E00H
  2208.     JB    SHORT SDCM2
  2209.     MOV    DMA_OFFSET,4000H
  2210.     MOV    MIXMUL_OFFSET,0
  2211. SDCM2:    CLC
  2212. SDCM1:  RET
  2213. SET_DMEM ENDP
  2214. ;----------------------------------------------------------------------------
  2215. ; DEALLOCATES MEMORY OF DMA & MIXMUL_VOLUMETABLE
  2216. ;----------------------------------------------------------------------------
  2217. FREE_DMEM PROC NEAR
  2218.     MOV    AX,DMA_SEG
  2219.     MOV    ES,AX
  2220.     MOV    AH,49H
  2221.     INT    21H
  2222.     RET
  2223. FREE_DMEM ENDP
  2224. ;-----------------------------------------------------------------------------
  2225. FREE_MEM PROC NEAR
  2226.     MOV     BX,PROG_END_SEG
  2227.     SUB     BX,PROG_START_SEG
  2228.     MOV     ES,PROG_START_SEG
  2229.     MOV     AH,4AH
  2230.     INT     21H
  2231.     RET
  2232. FREE_MEM ENDP
  2233. ;=============================================================================
  2234.  
  2235.  
  2236.  
  2237. ;=============================================================================
  2238. ;
  2239. ; SOUNDBLASTER HARDWARE ROUTINES
  2240. ;
  2241. ;=============================================================================
  2242. ; SET MIXER IF PRESENT
  2243. ;-----------------------------------------------------------------------------
  2244. MIXER_INIT PROC NEAR
  2245.     MOV    DX,SBP_MIXERI
  2246. COMMENT *                
  2247.     XOR    AL,AL            ;RESET MIXER SWITCHED OFF
  2248.     OUT    DX,AL            ;BECAUSE IT IS NOT WORKING PROPERLY
  2249.     MOV    CX,100            ;WITH SB16 ASP (GAIN x2,x3,..)
  2250.     CALL    WAIT_TIME
  2251.     MOV    DX,SBP_MIXERD
  2252.     XOR    AL,AL
  2253.     OUT    DX,AL
  2254.     DEC    DX
  2255.     *
  2256.     MOV    AL,22H
  2257.     OUT    DX,AL
  2258.     INC    DX
  2259.     MOV    AL,255            ;MAX MASTERVOLUME
  2260.     OUT    DX,AL
  2261.     DEC    DX
  2262.     MOV    AL,2
  2263.     OUT    DX,AL
  2264.     INC    DX
  2265.     MOV    AL,255            ;MAX DSPVOLUME
  2266.     OUT    DX,AL
  2267.     DEC    DX
  2268.     MOV    AL,0EH
  2269.     OUT    DX,AL
  2270.     INC    DX
  2271.     MOV    AL,0H            ;FILTER & MONO
  2272.     MOV    SBPRO_FLAG,AL
  2273.     CMP    SB_TYP,1        ;SBPRO ENABLED?
  2274.     JNE    SHORT GMIX1
  2275.     MOV    SBPRO_FLAG,1
  2276.     MOV    AL,2H            ;FILTER & STEREO
  2277. GMIX1:    OUT    DX,AL
  2278.     RET
  2279. MIXER_INIT ENDP
  2280. ;-----------------------------------------------------------------------------
  2281. ; SET DMA READY FOR TRANSFER WITH AUTOINIT
  2282. ; IN: DX:BX= BLOCKPOINTER, CX= SIZE
  2283. ;-----------------------------------------------------------------------------
  2284. DMA_INIT PROC NEAR
  2285.     MOV    AX,DX            ;CONVERT ADDRESS TO PAGE AND OFFSET
  2286.     SHL    DX,4
  2287.     SHR    AH,4            ;PAGE
  2288.     ADD    BX,DX            ;OFFSET NEW
  2289.     ADC    AH,0
  2290.     MOV    DMA_PAGE,AH
  2291.     MOV    DMA_POFF,BX
  2292.     DEC    CX            ;DMA SIZE= BLOCK SIZE -1
  2293.     MOV    AL,DMA_CHANNEL
  2294.     OR    AL,4
  2295.     OUT    0AH,AL            ;DMA-CHANNEL MASK
  2296.     AND    AL,3
  2297.     OR    AL,01011000B
  2298.     OUT    0BH,AL            ;DMA-MODUS FOR SB
  2299.     OUT    0CH,AL            ;FLIP-FLOP CLEAR
  2300.     AND    AL,3
  2301.     MOVZX    DX,AL
  2302.     SHL    DL,1
  2303.     MOV    AL,BL            ;DMA CHANNEL 1-4
  2304.     OUT    DX,AL            ;OFFSET LOW
  2305.     MOV    AL,BH
  2306.     OUT    DX,AL            ;OFFSET HIGH
  2307.     INC    DL
  2308.     MOV    AL,CL
  2309.     OUT    DX,AL            ;SIZE LOW
  2310.     MOV    AL,CH
  2311.     OUT    DX,AL            ;SIZE HIGH
  2312.     MOV    BX,DX
  2313.     SHR    BL,1
  2314.     MOV    DL,[DMA_DATA+BX]
  2315.     MOV    AL,AH
  2316.     OUT    DX,AL            ;PAGE
  2317.     MOV    AL,BL
  2318.     OUT    0AH,AL            ;DMA-CHANNEL DEMASK
  2319.     RET
  2320. DMA_INIT ENDP
  2321. ;-----------------------------------------------------------------------------
  2322. ; DSP SET SAMPLE RATE
  2323. ; IN: AH= RATE (= 256-(1000000/FREQ))
  2324. ;-----------------------------------------------------------------------------
  2325. DSP_RATE PROC NEAR
  2326.     PUSH    AX
  2327.     MOV    AH,40H
  2328.     CALL    DSP_WRITE
  2329.     POP    AX
  2330.     CALL    DSP_WRITE
  2331.     RET
  2332. DSP_RATE ENDP
  2333. ;-----------------------------------------------------------------------------
  2334. ; DSP OUT BLOCK
  2335. ;-----------------------------------------------------------------------------
  2336. DSP_OUT PROC NEAR
  2337.     CMP    SBPRO_FLAG,1
  2338.     JE    SHORT GDSP1
  2339.     MOV    AH,14H            ;MONO DMA-OUTPUT NEW
  2340.     CALL    DSP_WRITE
  2341.     MOV    AH,0FFH            ;SIZE LOW
  2342.     CALL    DSP_WRITE
  2343.     MOV    AH,0FFH            ;SIZE HIGH
  2344.     CALL    DSP_WRITE
  2345.     RET
  2346. GDSP1:    MOV    AH,48H            ;STEREO DMA-OUTPUT NEW
  2347.     CALL    DSP_WRITE
  2348.     MOV    AH,0FFH            ;SIZE LOW
  2349.     CALL    DSP_WRITE
  2350.     MOV    AH,0FFH            ;SIZE HIGH
  2351.     CALL    DSP_WRITE
  2352.     MOV    AH,91H            ;START
  2353.     CALL    DSP_WRITE
  2354.     RET
  2355. DSP_OUT ENDP
  2356. ;-----------------------------------------------------------------------------
  2357. ; DSP RESET
  2358. ; OUT: CARRY 1= FAILURE
  2359. ;-----------------------------------------------------------------------------
  2360. DSP_RESET PROC NEAR
  2361.     CALL    DSP_OFF
  2362.     OUT    0DH,AL            ;DMA MASTER CLEAR
  2363.     CALL    MIXER_INIT
  2364.     MOV    DX,SB_RESET
  2365.     MOV    AL,1
  2366.     OUT    DX,AL            ;SEND RESET COMMAND
  2367.     MOV    CX,4
  2368.     CALL    WAIT_TIME        ;WAIT
  2369.     XOR    AL,AL
  2370.     OUT    DX,AL            ;CLEAR RESET COMMAND
  2371.     MOV    CX,120
  2372.     CALL    WAIT_TIME        ;WAIT
  2373.     MOV    DX,SB_RSTAT
  2374.     IN    AL,DX            ;CHECK IF SUCCESSFUL
  2375.     OR    AL,AL
  2376.     JNS    SHORT GDRES1
  2377.     MOV    DX,SB_READ
  2378.     IN    AL,DX
  2379.     CMP    AL,0AAH
  2380.     JNE    SHORT GDRES1
  2381.     CALL    DSP_ON
  2382.     CLC                ;RESET OK
  2383.     RET
  2384. GDRES1:    STC                ;RESET FAILURE
  2385.     RET
  2386. DSP_RESET ENDP
  2387. ;-----------------------------------------------------------------------------
  2388. ; SPEAKER ON
  2389. ;-----------------------------------------------------------------------------
  2390. DSP_ON PROC NEAR
  2391.     MOV    AH,0D1H            ;SPEAKER ON
  2392.     CALL    DSP_WRITE
  2393.     MOV    CX,120
  2394.     CALL    WAIT_TIME        ;WAIT
  2395.     RET
  2396. DSP_ON ENDP
  2397. ;-----------------------------------------------------------------------------
  2398. ; SPEAKER OFF
  2399. ;-----------------------------------------------------------------------------
  2400. DSP_OFF PROC NEAR
  2401.     PUSH    CS
  2402.     POP    DS
  2403.     CMP    SB_TYP,1
  2404.     JE    SHORT GDSPF1        ;SB
  2405.     MOV    AL,DMA_CHANNEL        ;DMA DEMASK
  2406.     OUT    0AH,AL
  2407.     MOV    AH,0D0H            ;DMA STOP
  2408.     CALL    DSP_WRITE
  2409.     MOV    AH,0D3H            ;DSP OFF
  2410.     CALL    DSP_WRITE
  2411.     MOV    CX,240
  2412.     CALL    WAIT_TIME        ;WAIT
  2413.     RET
  2414. GDSPF1:    MOV    DX,SBP_MIXERI        ;SBPRO
  2415.     MOV    AL,22H
  2416.     OUT    DX,AL
  2417.     INC    DX
  2418.     MOV    AL,0            ;MIN MASTERVOLUME
  2419.     OUT    DX,AL
  2420.     DEC    DX
  2421.     MOV    AL,2
  2422.     OUT    DX,AL
  2423.     INC    DX
  2424.     MOV    AL,0            ;MIN DSPVOLUME
  2425.     OUT    DX,AL
  2426.     MOV    CX,240
  2427.     CALL    WAIT_TIME
  2428.     RET
  2429. DSP_OFF ENDP
  2430. ;-----------------------------------------------------------------------------
  2431. ; READ BYTE
  2432. ; OUT: AL= BYTE
  2433. ;-----------------------------------------------------------------------------
  2434. DSP_READ PROC NEAR
  2435.     MOV    DX,SB_READ
  2436.     MOV    CX,-1            ;FAIL SAFE
  2437. LDRD1:    IN    AL,DX
  2438.     CMP    AL,0AAH
  2439.     JNE    SHORT LDRD2
  2440.     LOOP    LDRD1
  2441. LDRD2:    RET
  2442. DSP_READ ENDP
  2443. ;-----------------------------------------------------------------------------
  2444. ; WRITE BYTE
  2445. ; IN: AH= BYTE
  2446. ;-----------------------------------------------------------------------------
  2447. DSP_WRITE PROC NEAR
  2448.     MOV    DX,SB_WRITE
  2449.     MOV    CX,1000H        ;FAIL SAFE
  2450. LDWR1:    IN    AL,DX
  2451.     OR    AL,AL
  2452.     JNS    SHORT LDWR2
  2453.     LOOP    LDWR1
  2454. LDWR2:    MOV    AL,AH
  2455.     OUT    DX,AL
  2456.     RET
  2457. DSP_WRITE ENDP
  2458. ;-----------------------------------------------------------------------------
  2459. ; WAIT TIME
  2460. ; CX = XXX MILLISECONDS
  2461. ;-----------------------------------------------------------------------------
  2462. WAIT_TIME PROC NEAR
  2463.     PUSH    AX BX EDX
  2464. LWT1:    IN    AL,TIMER0
  2465.     MOV    BL,AL
  2466.     IN    AL,TIMER0
  2467.     MOV    BH,AL
  2468.     MOV    EDX,500000        ;FAIL SAFE
  2469. LWT2:    IN    AL,TIMER0        ;1 MILLISEC WAIT
  2470.     XCHG    AL,AH
  2471.     IN    AL,TIMER0
  2472.     XCHG    AL,AH
  2473.     SUB    AX,BX
  2474.     NEG    AX
  2475.     DEC    EDX
  2476.     JZ    SHORT LWT3
  2477.     CMP    AX,1193
  2478.     JB    LWT2
  2479. LWT3:    LOOP    LWT1
  2480.     POP    EDX BX AX
  2481.     RET
  2482. WAIT_TIME ENDP
  2483. ;=============================================================================
  2484.  
  2485.  
  2486. ;=============================================================================
  2487. ;
  2488. ; MOD LOAD ROUTINES
  2489. ;
  2490. ;=============================================================================
  2491. ; LOAD A MODFILE
  2492. ; DS:DX= FILENAME
  2493. ;-----------------------------------------------------------------------------
  2494. LOAD_MOD PROC NEAR
  2495.     MOV    AX,3D00H        ;OPEN MOD
  2496.     INT    21H
  2497.     JC    GLDM1
  2498.     PUSH    CS
  2499.     POP    DS
  2500.     MOV    GDDHANDLE,AX
  2501. GLDM0:    CALL    SET_DMEM        ;ALLOCATE DMA-BUFFER 
  2502.     CALL    SET_TMEM        ;ALLOCATE TRACK-BUFFER
  2503.     MOV    BX,GDDHANDLE
  2504.     MOV    GDDZEIG,0
  2505.     MOV    CX,10            ;GET SONG-NAME
  2506. LLDM1:    CALL    GET_QUEUE
  2507.     JC    GLDM2
  2508.     LOOP    LLDM1
  2509.     MOV    SAMPLE_SIZE,0
  2510.     XOR    SI,SI            ;31 INSTRUMENTS
  2511. LLDM2:    MOV    AX,SAMPLE_SIZE
  2512.     MOV    [SAMPLE_SEG+SI],AX
  2513.     MOV    CX,11            ;INSTRUMENT NAME
  2514. LLDM3:    CALL    GET_QUEUE    
  2515.     JC    GLDM2
  2516.     LOOP    LLDM3
  2517.     XOR    EAX,EAX
  2518.     CALL    GET_QUEUE        ;INSTRUMENT SIZE
  2519.     XCHG    AL,AH
  2520.     CMP    AX,2
  2521.     JAE    SHORT GLDM20
  2522.     XOR    AX,AX
  2523. GLDM20:    SHL    AX,1
  2524.     MOV    [ISIZE+SI],AX        ;NO MORE THAN 64K
  2525.     OR    EAX,EAX
  2526.     JZ    SHORT GLDM9
  2527.     SHR    EAX,4
  2528.     INC    AX
  2529.     ADD    SAMPLE_SIZE,AX
  2530. GLDM9:    CALL    GET_QUEUE        ;IVOLUME & FINETUNE
  2531.     XCHG    AL,AH
  2532.     MOV    [IVOL_FINETUNE+SI],AX
  2533.     CALL    GET_QUEUE        ;ILOOP_START
  2534.     XCHG    AL,AH
  2535.     SHL    AX,1
  2536.     MOV    [ILOOP_START+SI],AX
  2537.     CALL    GET_QUEUE        ;ILOOP_SIZE
  2538.     XCHG    AL,AH
  2539.     SHL    AX,1
  2540.     MOV    [ILOOP_SIZE+SI],AX
  2541.     INC    SI
  2542.     INC    SI
  2543.     CMP    SI,62
  2544.     JB    LLDM2
  2545.     CALL    GET_QUEUE        ;SONG_SIZE & LOOP_BYTE OR NOTHING
  2546.     JC    GLDM2
  2547.     MOV    SONG_SIZE,AL
  2548.     MOV    SONG_LOOP,AH
  2549.     XOR    DX,DX
  2550.     MOV    CX,64            ;SONG_DATA
  2551.     MOV    DI,OFFSET SONG_DATA
  2552. LLDM4:    CALL    GET_QUEUE
  2553.     JC    GLDM2
  2554.     MOV    [DI],AX
  2555.     CMP    AL,DL            ;FIND HIGHEST PATTERN NUMBER
  2556.     JBE    SHORT GLDM12
  2557.     MOV    DL,AL
  2558. GLDM12:    CMP    AH,DL
  2559.     JBE    SHORT GLDM13
  2560.     MOV    DL,AH
  2561. GLDM13:    INC    DI
  2562.     INC    DI
  2563.     LOOP    LLDM4
  2564.     INC    DL
  2565.     CLD
  2566.     MOV    PATTERN_NUMBER,DX
  2567.     CALL    GET_QUEUE
  2568.     PUSH    AX
  2569.     CALL    GET_QUEUE
  2570.     SHL    EAX,16
  2571.     POP    AX
  2572.     MOV    MOD_SIGN,EAX
  2573.     CMP    EAX,"NHC8"        ;8CHN-MOD
  2574.     JE    SHORT GLDM3
  2575.     CMP    EAX,"8TLF"        ;FLT8-MOD
  2576.     JE    SHORT GLDM3
  2577.     CMP    EAX,".K.M"        ;M.K.-MOD
  2578.     JE    SHORT GLDM10
  2579.     CMP    EAX,"4TLF"        ;FLT4-MOD
  2580.     JNE    GLDM2
  2581.  
  2582. GLDM10:    MOV    CH_NUMB,4        ;4-CHANNEL-MOD
  2583.     MOV    PATTERN_SIZE,1024
  2584.     MOV    AH,0
  2585.     MOV    TRACK_INFO+4,AH
  2586.     MOV    TRACK_INFO+5,AH
  2587.     MOV    TRACK_INFO+6,AH
  2588.     MOV    TRACK_INFO+7,AH
  2589.     JMP    SHORT GLDM11
  2590. GLDM3:    MOV    CH_NUMB,8        ;8-CHANNEL-MOD: GET-PATTERNS
  2591.     MOV    PATTERN_SIZE,2048
  2592. GLDM11:    MOV    PATTERN_CURRENT,0
  2593.     MOV    TRACK_NUMBER,0
  2594. LLDM7:    MOV    ES,PATTERN_SEG
  2595.     MOV    BX,GDDHANDLE
  2596.     XOR    DI,DI
  2597. LLDM6:    XOR    SI,SI
  2598. LLDM5:    CALL    GET_QUEUE        ;GET PATTERNS AND SPLIT INTO TRACKS
  2599.     JC    GLDM2
  2600.     MOV    DX,AX
  2601.     CALL    GET_QUEUE
  2602.     JC    GLDM2
  2603.     ROL    AL,4            ;MODIFY PATTERN DATA
  2604.     MOV    CL,AL            ;LOOK AT PROTRACKER-CODE HEADER
  2605.     AND    AL,0FH
  2606.     AND    CL,0F0H    
  2607.     MOV    CH,DL
  2608.     AND    DL,0FH
  2609.     AND    CH,0F0H
  2610.     OR    AL,CH
  2611.     OR    DL,CL
  2612.     XCHG    DL,DH
  2613.     PUSH    DI
  2614.     ADD    DI,SI
  2615.     SHL    EAX,16
  2616.     MOV    AX,DX
  2617.     STOSD
  2618.     POP    DI
  2619.     ADD    SI,256
  2620.     CMP    SI,PATTERN_SIZE        ;NEXT TRACK/CHANNEL
  2621.     JB    LLDM5
  2622.     ADD    DI,4            ;NEXT NOTE
  2623.     CMP    DI,256
  2624.     JB    LLDM6
  2625.     CALL    SET_FREQUENCIES
  2626.     MOV    ES,TRACK_SEG        ;INTEGRATE TRACK1-8
  2627.     MOV    DX,TRACK_NUMBER
  2628.     XCHG    DL,DH
  2629.     MOV    DS,PATTERN_SEG
  2630.     XOR    SI,SI
  2631.     XOR    BX,BX
  2632. LLDM8:    XOR    DI,DI
  2633. LLDM9:    CMP    DX,DI
  2634.     JBE    SHORT GLDM4
  2635.     PUSH    SI DI
  2636.     MOV    CX,256/4
  2637.     REPE CMPSD            ;TRACK ALREADY EXISTS?
  2638.     POP    DI SI
  2639.     PUSHF
  2640.     ADD    DI,256
  2641.     POPF
  2642.     JNE    LLDM9
  2643.     JMP    SHORT GLDM5
  2644. GLDM4:    INC    DH            ;NO, ADD TRACK TO BUFFER
  2645.     PUSH    SI
  2646.     MOV    CX,256/4
  2647.     REP MOVSD
  2648.     POP    SI
  2649. GLDM5:    MOV    AX,DI            ;YES
  2650.     DEC    AH
  2651.     MOV    CS:[TRACK_INFO+BX],AH
  2652.     INC    BX
  2653.     ADD    SI,256
  2654.     CMP    BX,CS:CH_NUMB
  2655.     JB    LLDM8
  2656.     PUSH    CS
  2657.     POP    DS
  2658.     XCHG    DL,DH
  2659.     MOV    TRACK_NUMBER,DX
  2660.     XOR    BX,BX            ;MAKE TRACKLISTE 
  2661.     MOV    AX,PATTERN_CURRENT
  2662. LLDM10:    CMP    [SONG_DATA+BX],AL
  2663.     JNE    SHORT GLDM6
  2664.     MOV    AH,TRACK_INFO
  2665.     MOV    [TRACK1_DATA+BX],AH
  2666.     MOV    AH,TRACK_INFO+1
  2667.     MOV    [TRACK2_DATA+BX],AH
  2668.     MOV    AH,TRACK_INFO+2
  2669.     MOV    [TRACK3_DATA+BX],AH
  2670.     MOV    AH,TRACK_INFO+3
  2671.     MOV    [TRACK4_DATA+BX],AH
  2672.     MOV    AH,TRACK_INFO+4
  2673.     MOV    [TRACK5_DATA+BX],AH
  2674.     MOV    AH,TRACK_INFO+5
  2675.     MOV    [TRACK6_DATA+BX],AH
  2676.     MOV    AH,TRACK_INFO+6
  2677.     MOV    [TRACK7_DATA+BX],AH
  2678.     MOV    AH,TRACK_INFO+7
  2679.     MOV    [TRACK8_DATA+BX],AH
  2680. GLDM6:    INC    BX
  2681.     CMP    BL,128
  2682.     JB    LLDM10
  2683.     INC    PATTERN_CURRENT        ;GET NEXT PATTERN
  2684.     MOV    AX,PATTERN_CURRENT
  2685.     CMP    AX,PATTERN_NUMBER
  2686.     JB    LLDM7
  2687.  
  2688. GLDM7:    MOV    ES,PATTERN_SEG        ;CLEAR PATTERN SEGMENT
  2689.     MOV    AH,49H
  2690.     INT    21H
  2691.     MOV    BX,TRACK_NUMBER        ;TRACK SEGMENT RESIZE
  2692.     SHL    BX,4
  2693.     MOV    ES,TRACK_SEG
  2694.     MOV    AH,4AH
  2695.     INT    21H
  2696.     MOV    BX,SAMPLE_SIZE        ;SAMPLE SEGMENT ALLOCATE
  2697.     MOV    AH,48H
  2698.     INT    21H
  2699.     XOR    BX,BX
  2700. LLDM11:    ADD    [SAMPLE_SEG+BX],AX
  2701.     INC    BX
  2702.     INC    BX
  2703.     CMP    BX,62
  2704.     JB    LLDM11
  2705.     MOV    BX,GDDHANDLE
  2706.     XOR    SI,SI            ;LOAD SAMPLES
  2707. LLDM12:    MOV    CX,[ISIZE+SI]
  2708.     MOV    ES,[SAMPLE_SEG+SI]
  2709.     XOR    DI,DI
  2710.     SHR    CX,1
  2711.     JCXZ    SHORT GLDM8
  2712. LLDM13:    CALL    GET_QUEUE
  2713.     STOSW
  2714.     LOOP    LLDM13
  2715. GLDM8:    INC    SI
  2716.     INC    SI
  2717.     CMP    SI,62
  2718.     JB    LLDM12
  2719.     CLC
  2720.     JMP    SHORT GLDM15
  2721. GLDM2:    STC
  2722. GLDM15:    PUSHF
  2723.     MOV    AH,3EH
  2724.     INT    21H
  2725.     POPF
  2726. GLDM1:    RET
  2727. LOAD_MOD ENDP
  2728. ;-----------------------------------------------------------------------------
  2729. ; REPLACE MOST PERIODS WITH INDEX INTO PERIOD TABLE
  2730. ;-----------------------------------------------------------------------------
  2731. SET_FREQUENCIES PROC NEAR
  2732.     XOR    DI,DI
  2733. SET_FREQ1:
  2734.     MOV    AX,ES:[DI]        ;get fx
  2735.     MOV    DX,AX
  2736.     SHR    AH,4
  2737.     CMP    AH,3
  2738.     JE    SHORT SET_FREQ4
  2739.     CMP    AH,5
  2740.     JE    SHORT SET_FREQ4
  2741.     MOV    AX,DX
  2742.     AND    AX,0FFFH        ; Mask out unwanted bits.
  2743.     JZ    SHORT SET_FREQ4
  2744.     XOR    BX,BX
  2745.     MOV    CX,48            ; 36 periods to cycle through.
  2746. SET_FREQ2:
  2747.     CMP    AX,[MT_PERIODTABLE+BX]    ; Check the note against the period.
  2748.     JAE    SHORT SET_FREQ3        ; We found it!
  2749.     INC    BX            ; Otherwise, update the pointer and
  2750.     INC    BX
  2751.     LOOP    SET_FREQ2        ; keep looping.
  2752. SET_FREQ3:
  2753.     MOV    AX,DX            ;recall the Note Value
  2754.     AND    AX,0F000H        ;just keep fx
  2755.     INC    BX
  2756.     OR    AX,BX            ;put in the new offset
  2757.     STOSW                ;store it
  2758.     DEC    DI
  2759.     DEC    DI
  2760. SET_FREQ4:
  2761.     ADD    DI,4            ;and go to next channel
  2762.     CMP    DI,PATTERN_SIZE
  2763.     JB    SET_FREQ1
  2764.     RET
  2765. SET_FREQUENCIES ENDP
  2766. ;-----------------------------------------------------------------------------
  2767. ; GET WORD FROM BUFFER
  2768. ; IN: AX= WORD, BX= HANDLE
  2769. ;-----------------------------------------------------------------------------
  2770. GET_QUEUE PROC NEAR
  2771.     CMP     GDDZEIG,0
  2772.     JNE     SHORT GTQ1
  2773.     PUSH    CX DX
  2774.     MOV     DX,OFFSET QUEUE_BUFFER
  2775.     MOV     CX,256
  2776.     MOV     AH,3FH
  2777.     INT     21H
  2778.     MOV    GDDREST,AX
  2779.     POP    DX CX
  2780. GTQ1:   PUSH    BX
  2781.     MOV     BL,GDDZEIG
  2782.     XOR     BH,BH
  2783.     CMP    BX,GDDREST
  2784.     JAE    SHORT GTQ2
  2785.     MOV     AX,[QUEUE_BUFFER+BX]
  2786.     ADD     GDDZEIG,2
  2787.     POP    BX
  2788.     CLC
  2789.     RET
  2790. GTQ2:    POP    BX
  2791.     STC
  2792.     RET
  2793. GET_QUEUE ENDP
  2794. ;=============================================================================
  2795. ; LOAD A SAMPLE
  2796. ; INPUT: DS:DX= FILENAME, CL= 00H AMIGA-SAMPLE, 80H PC-SAMPLE
  2797. ; OUTPUT: AX= SAMPLE-HANDLE FOR PLAYING
  2798. ;-----------------------------------------------------------------------------
  2799. LOAD_SAMPLE PROC NEAR
  2800.     MOV    AX,3D00H        ;OPEN SAMPLE
  2801.     INT    21H
  2802.     JC    GSMP1
  2803.     PUSH    CS
  2804.     POP    DS
  2805.     MOV    GDDHANDLE,AX
  2806.     MOV    BX,AX
  2807.     PUSH    CX
  2808.     CALL    GET_FILESIZE
  2809.     POP    CX
  2810. GSMP0:    AND    CL,80H
  2811.     MOV    SAM_FLAG,CL
  2812.     MOV    GDDZEIG,0
  2813.     MOV    CX,AX
  2814.     AND    CX,0FFFEH
  2815.     SHR    AX,4
  2816.     INC    AX
  2817.     MOV    BX,AX
  2818.     CMP    EMS_SEG,0
  2819.     JNE    SHORT GSMP3
  2820.     PUSHA
  2821.     XOR    SI,SI
  2822.     XOR    AX,AX            ;CHECK FOR EMS-MANAGER
  2823.     MOV    ES,AX
  2824.     MOV    EMS_HANDLE,AX
  2825.     MOV    AX,ES:[4*67H+2]
  2826.     MOV    ES,AX
  2827.     CMP    ES:[10],"XMME"
  2828.     JNE    GSMP2
  2829.     CMP    ES:[14],"0XXX"
  2830.     JNE    GSMP2
  2831.     MOV    AH,42H
  2832.     INT    67H
  2833.     OR    AH,AH
  2834.     JNZ    GSMP2
  2835.     CMP    BX,34
  2836.     JB    GSMP2
  2837.     MOV    AH,41H
  2838.     INT    67H
  2839.     MOV    EMS_SEG,BX
  2840.     MOV    AH,43H            ;ALLOCATE 544K EMS FOR FX
  2841.     MOV    BX,34
  2842.     INT    67H
  2843.     MOV    EMS_HANDLE,DX
  2844.     XOR    AX,AX
  2845.     MOV    EMS_OFFSET,AX
  2846.     MOV    SAMPLE_ZEIG,AX
  2847.     POPA
  2848. GSMP3:    MOV    AX,EMS_OFFSET
  2849.     MOV    SI,SAMPLE_ZEIG
  2850.     MOV    [SAMPLE_MEM+SI],AX
  2851.     MOV    [SAMPLE_BIG+SI],CX
  2852.     ADD    SAMPLE_ZEIG,2
  2853.     MOV    DI,CX
  2854.     SHR    DI,4
  2855.     INC    DI
  2856.     ADD    EMS_OFFSET,DI
  2857.     XOR    DI,DI
  2858.     CLD
  2859.     INC    CX
  2860.     SHR    CX,1
  2861.     MOV    DL,SAM_FLAG
  2862.     MOV    DH,DL
  2863.     MOVZX    BP,FX_VOL
  2864.     INC    BP
  2865.     AND    EAX,0FFFFH
  2866.     SHL    EAX,4
  2867. LSMP1:    PUSH    EAX
  2868.     OR    DI,DI
  2869.     JNZ    SHORT GSMP4
  2870.     CALL    EMS_PAGING
  2871. GSMP4:    MOV    BX,GDDHANDLE
  2872.     CALL    GET_QUEUE
  2873.     XOR    AX,DX
  2874.     SAR    AH,1
  2875.     SAR    AL,1
  2876.     PUSH    DX
  2877.     MOV    BL,AH
  2878.     CBW
  2879.     IMUL    BP
  2880.     MOV    AL,BL
  2881.     MOV    BL,AH
  2882.     CBW
  2883.     IMUL    BP
  2884.     MOV    AL,BL
  2885.     POP    DX
  2886.     STOSW
  2887.     POP    EAX
  2888.     INC    EAX
  2889.     INC    EAX
  2890.     LOOP    LSMP1
  2891.     CLC
  2892. GSMP2:    PUSHF
  2893.     MOV    BX,GDDHANDLE
  2894.     MOV    AH,3EH
  2895.     INT    21H
  2896.     MOV    AX,SI
  2897.     POPF
  2898. GSMP1:    RET
  2899. LOAD_SAMPLE ENDP
  2900. ;-----------------------------------------------------------------------------
  2901. GET_FILESIZE PROC NEAR
  2902.     MOV    AX,4202H
  2903.     XOR    CX,CX
  2904.     XOR    DX,DX
  2905.     INT    21H
  2906.     PUSH    AX
  2907.     MOV    AX,4200H
  2908.     XOR    CX,CX
  2909.     XOR    DX,DX
  2910.     INT    21H
  2911.     POP    AX
  2912.     RET
  2913. GET_FILESIZE ENDP
  2914. ;=============================================================================
  2915. ; LOAD CONFIG DATA (PARSER)
  2916. ;-----------------------------------------------------------------------------
  2917. CONFIG_INIT PROC NEAR
  2918.     MOV    AX,CS            ;SAVE THE SEGMENT OF CODE
  2919.     MOV    DS,AX
  2920.     MOV    WORD PTR HOLD70+2,AX    ;THIS LINE IS IMPORTANT
  2921.     MOV    WORD PTR HOLDSB+2,AX    ;THIS LINE IS IMPORTANT
  2922.     MOV     DX,OFFSET CONFIG_NAME
  2923.     MOV     AH,3DH
  2924.     MOV     AL,80H
  2925.     INT     21H
  2926.     JC      GCFG1
  2927.     MOV     GDDHANDLE,AX
  2928. LCFG1:  XOR     SI,SI
  2929.     MOV     DX,OFFSET QUEUE_BUFFER
  2930. LCFG2:  MOV     AH,3FH
  2931.     MOV     BX,GDDHANDLE
  2932.     MOV     CX,1
  2933.     INT     21H
  2934.     JC      GCFG2
  2935.     OR      AX,AX
  2936.     JZ      GCFG2
  2937.     MOV     DI,DX
  2938.     CMP     BYTE PTR [DI],0AH
  2939.     JE      SHORT GCFG6
  2940.     INC     DX
  2941.     INC     SI
  2942.     CMP     SI,256
  2943.     JB      LCFG2
  2944. GCFG6:  MOV     BX,OFFSET CFG_TEXT1
  2945.     CALL    SEEK_LINE
  2946.     JNC     SHORT GCFG3
  2947.     LODSB
  2948.     AND     AL,3
  2949.     MOV    SB_TYP,AL
  2950.     JMP     LCFG1
  2951. GCFG3:  MOV     BX,OFFSET CFG_TEXT2
  2952.     CALL    SEEK_LINE
  2953.     JNC     SHORT GCFG4
  2954.     LODSB
  2955.     AND     AL,3
  2956.     MOV    SB_MODUS,AL
  2957.     JMP     LCFG1
  2958. GCFG4:  MOV     BX,OFFSET CFG_TEXT3
  2959.     CALL    SEEK_LINE
  2960.     JNC     SHORT GCFG5
  2961.     INC    SI
  2962.     LODSB
  2963.     DEC    AL
  2964.     AND    AL,7
  2965.     INC    AL
  2966.     SHL    AL,4
  2967.     MOV    AH,2
  2968.     ADD    AL,4
  2969.     MOV    SBP_MIXERI,AX
  2970.     INC    AX
  2971.     MOV    SBP_MIXERD,AX
  2972.     INC    AX
  2973.     MOV    SB_RESET,AX
  2974.     ADD    AX,4
  2975.     MOV    SB_READ,AX
  2976.     ADD    AX,2
  2977.     MOV    SB_WRITE,AX
  2978.     ADD    AX,2
  2979.     MOV    SB_RSTAT,AX
  2980.     JMP     LCFG1
  2981. GCFG5:  MOV     BX,OFFSET CFG_TEXT4
  2982.     CALL    SEEK_LINE
  2983.     JNC     SHORT GCFG7
  2984.     LODSW
  2985.     AND     AL,7
  2986.     AND    AH,7
  2987.     MOV    BH,AH
  2988.     MOV    BL,10
  2989.     MUL    BL
  2990.     ADD    AL,BH
  2991.     MOV    IRQ_NUMBER,AL
  2992.     JMP    LCFG1
  2993. GCFG7:  MOV     BX,OFFSET CFG_TEXT5
  2994.     CALL    SEEK_LINE
  2995.     JNC     SHORT GCFG8
  2996.     LODSB
  2997.     AND    AL,3
  2998.     MOV    DMA_CHANNEL,AL
  2999.     JMP    LCFG1
  3000. GCFG8:    MOV    BX,OFFSET CFG_TEXT6
  3001.     CALL    SEEK_LINE
  3002.     JNC    SHORT GCFG9
  3003.     XOR    BX,BX
  3004.     MOV    CX,5
  3005. LCFG3:    MOV    AX,BX
  3006.     MOV    DX,10
  3007.     MUL    DX
  3008.     MOV    BX,AX
  3009.     LODSB
  3010.     AND    AL,0FH
  3011.     XOR    AH,AH
  3012.     ADD    BX,AX
  3013.     LOOP    LCFG3
  3014.     MOV    SAMPLE_RATE,BX
  3015.     JMP     LCFG1
  3016. GCFG9:    MOV     BX,OFFSET CFG_TEXT7
  3017.     CALL    SEEK_LINE
  3018.     JNC     LCFG1
  3019.     LODSB
  3020.     AND     AL,1
  3021.     MOV     SYSTEM,AL
  3022.     JMP     LCFG1
  3023. GCFG2:  MOV     BX,GDDHANDLE
  3024.     MOV     AH,3EH
  3025.     INT     21H
  3026. GCFG1:  RET
  3027. CONFIG_INIT ENDP
  3028. ;-----------------------------------------------------------------------------
  3029. SEEK_LINE PROC NEAR
  3030.     CLD
  3031.     MOV     SI,OFFSET QUEUE_BUFFER
  3032. LSKL1:  PUSH    BX
  3033. LSKL2:  CMP     BYTE PTR [BX],0
  3034.     JE      SHORT GSKL1
  3035.     CMP     SI,DX
  3036.     JAE     SHORT GSKL2
  3037.     LODSB
  3038.     CMP     AL,[BX]
  3039.     JNE     SHORT GSKL3
  3040.     INC     BX      
  3041.     JMP     LSKL2
  3042. GSKL3:  POP     BX
  3043.     JMP     LSKL1
  3044. GSKL2:  POP     BX
  3045.     CLC
  3046.     RET
  3047. GSKL1:  POP     BX
  3048.     STC
  3049.     RET
  3050. SEEK_LINE ENDP
  3051. ;=============================================================================
  3052.  
  3053.  
  3054. ;=============================================================================
  3055. PLAY_MUSIC PROC NEAR
  3056.     PUSH    CS
  3057.     POP    DS
  3058.     MOV    MOD_STAT,0        ;DEACTIVATE IRQ-HANDLING
  3059.     CALL    DSP_RESET
  3060.     JC    GPM1
  3061.     CALL    MAKE_MIXMUL_VOLUMETABLE
  3062.     CALL    IRQ_INIT
  3063.     XOR    EDX,EDX
  3064.     MOV    EAX,1000000
  3065.     MOVZX    EBX,SAMPLE_RATE
  3066.     MOV    CL,SBPRO_FLAG
  3067.     DIV    EBX
  3068.     SHR    AL,CL
  3069.     NEG    AL
  3070.     MOV    DMA_RATE,AL
  3071.     XOR    EDX,EDX
  3072.     MOV    EAX,369E9400H        ;1,193,180 * 300H FOR FREQ CALCS
  3073.     DIV    EBX
  3074.     MOV    MAINFREQ,EAX
  3075.     MOV    AX,BX
  3076.     MOV    BX,20            ;AMIGA TIMING IS 50HZ (SCREEN-REFRESH)
  3077.     MUL    BX
  3078.     SHRD    AX,DX,10
  3079.     SHL    AX,CL
  3080.     MOV    DMA_CX,AX        ;# OF BYTE/CYCLE (434 FOR 22222 HZ)
  3081.     SHL    AX,2            ;4 TIMES FORWARD
  3082.     MOV    DMA_MORE,AX
  3083.     SHL    AX,2            ;16 TIMES MAXIMUM (6944 FOR 22222 HZ)
  3084.     SHR    AX,CL
  3085.     SUB    AH,CL
  3086.     SUB    AH,CL
  3087.     MOV    DMA_MAX,AX
  3088.     MOV    AX,DMA_OFFSET
  3089.     MOV    DMA_PTR,AX
  3090.     MOV    DMA_NEWPTR,AX
  3091.     MOV    BPM_SPEED,20        ;CLOCK-IRQ IS 1024HZ DIV 20 = 50HZ
  3092.     MOV    BPM_COUNT,1
  3093.     MOV    MT_SPEED,6        ;DEFAULT PROTRACKER SPEED
  3094.     XOR    AX,AX
  3095.     MOV    MT_COUNTER,AL        ;RESET PROTRACKER VARIABLES
  3096.     MOV    MT_PATTERNPOS,AX
  3097.     MOV    MT_SONGPOS,AL
  3098.     MOV    MT_PATTDELAYTIME2,AL
  3099.     MOV    MT_PATTDELAYTIME,AL
  3100.     MOV    MT_PBREAKFLAG,AL
  3101.     MOV    MT_PBREAKPOS,AL
  3102.     MOV    MT_POSJUMPFLAG,AL
  3103.     MOV    MT_LOWMASK,0FFH
  3104.     MOV    CX,43*8/2
  3105.     CLD
  3106.     PUSH    DS
  3107.     POP    ES
  3108.     MOV    DI,OFFSET NOTE
  3109.     REP STOSW
  3110.     INC    AL
  3111.     MOV    CX,MAX_CHAN_NUMB
  3112.     MOV    DI,OFFSET TONEPORTDIREC
  3113.     REP STOSB
  3114.     MOV    BYTE PTR SELFN1+2,2
  3115.     MOV    BYTE PTR SELFN2+2,2
  3116.     TEST    SBPRO_FLAG,1
  3117.     JZ    SHORT GPM2
  3118.     MOV    BYTE PTR SELFN1+2,4
  3119.     MOV    BYTE PTR SELFN2+2,4
  3120. GPM2:    MOV    CX,3            ;PRECALCULATE SAMPLE DATA FOR INIT
  3121. LPM1:    PUSH    CX
  3122.     CALL    CONTROL_CHANNELS
  3123.     CALL    MIXUP_CHANNELS
  3124.     POP    CX
  3125.     LOOP    LPM1
  3126.     MOV    AH,DMA_RATE        ;SET SB-SAMPLERATE
  3127.     CALL    DSP_RATE
  3128.     MOV    DX,DMA_SEG        ;INITIALIZE DMA
  3129.     MOV    BX,DMA_OFFSET
  3130.     MOV    CX,DMA_MAX
  3131.     CALL    DMA_INIT
  3132.     MOV    MOD_STAT,1        ;ACTIVATE IRQ-HANDLING
  3133.     CLC
  3134. GPM1:    RET
  3135. PLAY_MUSIC ENDP
  3136. ;-----------------------------------------------------------------------------
  3137. STOP_MUSIC PROC NEAR
  3138.     PUSH    CS
  3139.     POP    DS
  3140.     MOV    MOD_STAT,0
  3141.     CALL    DSP_RESET
  3142.     CALL    IRQ_INIT
  3143.     MOV    IRQCOUNT,56
  3144.     RET
  3145. STOP_MUSIC ENDP
  3146. ;-----------------------------------------------------------------------------
  3147. END_MUSIC PROC NEAR
  3148.     PUSH    CS
  3149.     POP    DS
  3150.     CALL    FREE_TMEM
  3151.     CALL    FREE_DMEM
  3152.     RET
  3153. END_MUSIC ENDP
  3154. ;-----------------------------------------------------------------------------
  3155. GET_SONGMOD PROC NEAR
  3156.     MOV    AL,CS:SB_MODUS
  3157.     RET
  3158. GET_SONGMOD ENDP
  3159. ;-----------------------------------------------------------------------------
  3160. SET_SONGMOD PROC NEAR
  3161.     AND    AL,3
  3162.     MOV    CS:SB_MODUS,AL
  3163.     RET
  3164. SET_SONGMOD ENDP
  3165. ;-----------------------------------------------------------------------------
  3166. GET_SONGPOSITION PROC NEAR
  3167.     MOV    AL,CS:MT_SONGPOS
  3168.     RET
  3169. GET_SONGPOSITION ENDP
  3170. ;-----------------------------------------------------------------------------
  3171. SET_SONGPOSITION PROC NEAR
  3172.     AND    AL,7FH
  3173.     MOV    CS:MT_SONGPOS,AL
  3174.     MOV    CS:MT_PATTERNPOS,0
  3175.     RET
  3176. SET_SONGPOSITION ENDP
  3177. ;-----------------------------------------------------------------------------
  3178. SET_SONGLOOP PROC NEAR
  3179.     MOV    CS:SONG_LOOP,AL
  3180.     RET
  3181. SET_SONGLOOP ENDP
  3182. ;-----------------------------------------------------------------------------
  3183. GET_VOLUME PROC NEAR
  3184.     MOV    AL,CS:MASTER_VOLUME    ;0= MIN VOLUME, 255= MAX VOLUME
  3185.     MOV    BL,CS:MUSIC_VOLUME    ;0= MIN VOLUME, 255= MAX VOLUME
  3186.     MOV    BH,CS:FX_VOLUME        ;0= MIN VOLUME, 255= MAX VOLUME
  3187.     RET
  3188. GET_VOLUME ENDP
  3189. ;-----------------------------------------------------------------------------
  3190. SET_VOLUME PROC NEAR
  3191.     MOV    CS:MASTER_VOLUME,AL    ;0= MIN VOLUME, 255= MAX VOLUME
  3192.     MOV    CS:MUSIC_VOLUME,BL    ;0= MIN VOLUME, 255= MAX VOLUME
  3193.     MOV    CS:FX_VOLUME,BH        ;0= MIN VOLUME, 255= MAX VOLUME
  3194.     PUSH    AX DX
  3195.     MOVZX    DX,AL
  3196.     INC    DX
  3197.     PUSH    DX
  3198.     MOVZX    AX,BL
  3199.     MUL    DX
  3200.     MOV    CS:MUSIC_VOL,AH
  3201.     POP    DX
  3202.     MOVZX    AX,BH
  3203.     MUL    DX
  3204.     MOV    CS:FX_VOL,AH
  3205.     POP    DX AX
  3206.     RET
  3207. SET_VOLUME ENDP
  3208. ;-----------------------------------------------------------------------------
  3209. SET_SAMPLERATE PROC NEAR
  3210.     CMP    AX,10000
  3211.     JAE    SHORT GSSR1
  3212.     MOV    AX,10000
  3213. GSSR1:    CMP    AX,22222
  3214.     JBE    SHORT GSSR2
  3215.     MOV    AX,22222
  3216. GSSR2:    MOV    CS:SAMPLE_RATE,AX    ;BEST BETWEEN 10000 - 22222 Hz
  3217.     RET
  3218. SET_SAMPLERATE ENDP
  3219. ;-----------------------------------------------------------------------------
  3220. ; START FX SAMPLE
  3221. ; BX= SAMPLE-HANDLE, CX= SAMPLERATE
  3222. ;-----------------------------------------------------------------------------
  3223. PLAY_SAMPLE PROC NEAR
  3224.     PUSH    CS
  3225.     POP    DS
  3226.     TEST    SB_MODUS,1
  3227.     JNZ    GPSMP1
  3228.     CMP    EMS_SEG,0
  3229.     JE    GPSMP1
  3230.     MOVZX    EAX,CX    
  3231.     SHL    EAX,8
  3232.     MOVZX    ECX,SAMPLE_RATE
  3233.     XOR    EDX,EDX
  3234.     DIV    ECX
  3235.     OR    AX,AX
  3236.     JZ    SHORT GPSMP1
  3237.     CMP    SBPRO_FLAG,1
  3238.     JNE    SHORT GPSMP2
  3239.     XOR    SAM_FLAG,1
  3240.     TEST    SAM_FLAG,1
  3241.     JZ    SHORT GPSMP3
  3242.     CMP    SAM_SEG1,0
  3243.     JE    SHORT GPSMP2
  3244.     CMP    SAM_SEG2,0
  3245.     JNE    SHORT GPSMP2
  3246. GPSMP4:    CLI                ;RIGHT CHANNEL SAMPLE
  3247.     MOV    SAM_FRQ2,AX
  3248.     MOV    AX,EMS_SEG
  3249.     MOV    SAM_SEG2,AX
  3250.     MOVZX    EAX,[SAMPLE_MEM+BX]
  3251.     SHL    EAX,4
  3252.     MOV    SAM_OFS2,EAX
  3253.     MOV    AX,[SAMPLE_BIG+BX]
  3254.     MOV    SAM_MAX2,AX
  3255.     MOV    SAM_OFL2,0
  3256.     STI
  3257.     RET
  3258. GPSMP3:    CMP    SAM_SEG2,0
  3259.     JE    GPSMP4
  3260.     CMP    SAM_SEG1,0
  3261.     JNE    GPSMP4
  3262. GPSMP2:    CLI                ;LEFT CHANNEL SAMPLE
  3263.     MOV    SAM_FRQ1,AX
  3264.     MOV    AX,EMS_SEG
  3265.     MOV    SAM_SEG1,AX
  3266.     MOVZX    EAX,[SAMPLE_MEM+BX]
  3267.     SHL    EAX,4
  3268.     MOV    SAM_OFS1,EAX
  3269.     MOV    AX,[SAMPLE_BIG+BX]
  3270.     MOV    SAM_MAX1,AX
  3271.     MOV    SAM_OFL1,0
  3272.     STI
  3273. GPSMP1:    RET
  3274. PLAY_SAMPLE ENDP
  3275. ;-----------------------------------------------------------------------------
  3276. END_SAMPLE PROC NEAR
  3277.     PUSH    CS
  3278.     POP    DS
  3279.     MOV    SAM_SEG1,0
  3280.     MOV    SAM_SEG2,0
  3281.     CMP    EMS_SEG,0
  3282.     JE    SHORT GEMP1
  3283.     MOV    AH,45H
  3284.     MOV    DX,EMS_HANDLE
  3285.     INT    67H
  3286.     MOV    EMS_SEG,0
  3287. GEMP1:    RET
  3288. END_SAMPLE ENDP
  3289. ;=============================================================================
  3290.  
  3291.  
  3292. ;=============================================================================
  3293. ;
  3294. ; MAIN ROUTINE
  3295. ;
  3296. ;=============================================================================
  3297. MAIN_CONT PROC NEAR
  3298.     MOV    AX,CS            ;DS SET
  3299.     MOV    DS,AX
  3300.     MOV     PROG_START_SEG,ES       ;PROGRAMM START
  3301.     MOV     AX,SS                   ;AND -END SET
  3302.     MOV     BX,OFFSET PROG_END
  3303.     ADD     BX,STACKLENGTH
  3304.     MOV     SP,BX
  3305.     SHR     BX,4
  3306.     INC     BX
  3307.     ADD     AX,BX
  3308.     MOV     PROG_END_SEG,AX
  3309.     XOR    BX,BX
  3310. GL1:    MOV    AL,ES:[82H+BX]
  3311.     OR    AL,AL
  3312.     JZ    SHORT GL2
  3313.     CMP    AL,20H
  3314.     JE    SHORT GL2
  3315.     CMP    AL,0DH
  3316.     JE    SHORT GL2
  3317.     MOV    [MOD_NAME+BX],AL
  3318.     INC    BX
  3319.     CMP    BX,40H
  3320.     JB    GL1
  3321. GL2:    OR    BX,BX
  3322.     JZ    GMEND
  3323.     XOR    AL,AL
  3324.     MOV    [MOD_NAME+BX],0
  3325.     CALL    FREE_MEM
  3326. ;-----------------------------------------------------------------------------
  3327. ; INITIALIZING & STARTING
  3328. ;    MOV    AX,22222        ;SET MAXIMUM SAMPLERATE
  3329. ;    CALL    SET_SAMPLERATE
  3330. ;    MOV    AL,255            ;SET MAXIMUM VOLUME
  3331. ;    MOV    BL,AL
  3332. ;    MOV    BH,AL
  3333. ;    CALL    SET_VOLUME
  3334.     CALL    CONFIG_INIT        ;GET CONFIG
  3335.     MOV    DX,OFFSET MOD_NAME    ;FIRST, TRY LOADING
  3336.     CALL    LOAD_MOD
  3337.     JNC    SHORT GM1
  3338.     MOV    AH,9
  3339.     MOV    DX,OFFSET ERROR1_TEXT
  3340.     INT    21H
  3341.     JMP    SHORT GM4
  3342. GM1:    MOV    DX,OFFSET SAMPLE_NAME    ;GET SAMPLE
  3343.     MOV    CL,80H            ;PC-SAMPLE
  3344.     CALL    LOAD_SAMPLE
  3345.     JNC    SHORT GM2
  3346.     MOV    AH,9
  3347.     MOV    DX,OFFSET ERROR2_TEXT
  3348.     INT    21H
  3349. GM2:    CALL    PLAY_MUSIC        ;TRY STARTING
  3350.     JNC    SHORT GM3
  3351.     MOV    AH,9
  3352.     MOV    DX,OFFSET ERROR3_TEXT
  3353.     INT    21H
  3354.     JMP    SHORT GM4
  3355. ;-----------------------------------------------------------------------------
  3356. ; THIS COULD BE THE MAIN ROUTINE
  3357. GM3:    MOV    AH,9
  3358.     MOV    DX,OFFSET OUT_TEXT
  3359.     INT    21H
  3360. LM1:    XOR    AH,AH
  3361.     INT    16H
  3362.     CMP    AL,27
  3363.     JE    SHORT GM5
  3364.     CMP    AL,"+"
  3365.     JNE    SHORT G1
  3366.     CALL    GET_VOLUME
  3367.     INC    AL
  3368.     CALL    SET_VOLUME
  3369.     JMP    LM1
  3370. G1:    CMP    AL,"-"
  3371.     JNE    SHORT G2
  3372.     CALL    GET_VOLUME
  3373.     DEC    AL
  3374.     CALL    SET_VOLUME
  3375.     JMP    LM1
  3376. G2:    CMP    AL,"9"
  3377.     JNE    SHORT G3
  3378.     MOV    AL,0
  3379.     CALL    SET_SONGLOOP
  3380.     JMP    LM1
  3381. G3:    CMP    AL,"0"
  3382.     JNE    SHORT G4
  3383.     INC    SB_MODUS
  3384.     AND    SB_MODUS,3
  3385.     JMP    LM1
  3386. G4:    CMP    AL,"1"
  3387.     JNE    LM1
  3388.     XOR    BX,BX            ;HANDLE
  3389.     MOV    CX,22222        ;FREQUENCE
  3390.     CALL    PLAY_SAMPLE
  3391.     JMP    LM1
  3392. ;-----------------------------------------------------------------------------
  3393. ; CUTTING OFF
  3394. GM5:    CALL    STOP_MUSIC        ;STOP MUSIC
  3395. GM4:    CALL    END_SAMPLE        ;UNLOAD SAMPLES
  3396.     CALL    END_MUSIC        ;UNLOAD MUSIC
  3397. GMEND:    MOV     AX,4C00H                ;DOS
  3398.     INT     21H
  3399. MAIN_CONT ENDP
  3400. ;=============================================================================
  3401.  
  3402. END MAIN